มีวิธีการแสดง "ถ้า" ในแลมบ์ดาของงูใหญ่หรือไม่


358

ในpython 2.6ฉันต้องการ:

f = lambda x: if x==2 print x else raise Exception()
f(2) #should print "2"
f(3) #should throw an exception

ชัดเจนว่านี่ไม่ใช่ไวยากรณ์ มันเป็นไปได้ที่จะดำเนินการifในlambdaและถ้าเป็นเช่นนั้นจะทำอย่างไร?

ขอบคุณ


2
คุณไม่สามารถพิมพ์หรือยกระดับแลมบ์ดาได้ แลมบ์ดาเป็นเพียงแค่ฟังก์ชั่นคุณสามารถใช้ฟังก์ชั่นแทนได้เสมอ
Lennart Regebro

10
ฉันไม่เห็นด้วยกับคุณ. ฉันต้องการฟังก์ชั่นสั้น ๆ ที่แตกต่างกัน 4 อย่างเช่นที่กล่าวมาข้างต้นซึ่งจำเป็นต้องใส่ไว้ในรายการ / พจนานุกรมเพื่อที่ฉันจะได้ย้ำพวกมันและเลือกสิ่งที่จะใช้ในการทำซ้ำแต่ละครั้ง แทนที่จะเป็นโค้ดหลายบรรทัดเพียง inits ก่อนการวนซ้ำตัวเองฉันสามารถนำมันลงไปเพียง 4 บรรทัดของโค้ด init หักด้วย merrier ..
ผู้ชาย

5
รหัส 4 บรรทัดไม่ใช่วิธีที่น่ายกย่องเมื่อผู้อื่นต้องอ่านตีความเข้าใจและรักษารหัส นอกจากนี้ปัญหา "พิมพ์ / ยก" ในตัวอย่างแสดงสิ่งนี้ซึ่งไม่สามารถและไม่ควรทำใน lambdas
S.Lott

@ LennartRegebro lambdas ไม่ได้ทำงานในภาษาไพ ธ อนพวกเขาเป็นเพียงการแสดงออกนั่นคือสาเหตุที่มีหลายสิ่งที่คุณไม่สามารถทำได้
Aaron McMillin

1
@AaronMcMillin Lambdas เป็นฟังก์ชั่น พวกเขาถูก จำกัด การแสดงออกเพราะเหตุผลทางไวยากรณ์ แต่พวกเขาฟังก์ชั่น
Lennart Regebro

คำตอบ:


660

ไวยากรณ์ที่คุณกำลังมองหา:

lambda x: True if x % 2 == 0 else False

แต่คุณไม่สามารถใช้printหรือraiseแลมบ์ดาได้


33
ในหลาม 3 คุณสามารถใช้พิมพ์
recursive

11
แน่นอน แต่คำถามคือ "ฉันจะใช้ifในแลมบ์ดาได้อย่างไร" ไม่ใช่ "วิธีที่ดีที่สุดในการเขียนแลมบ์ดาที่ส่งคืนค่า True หากตัวเลขเป็นเลขคู่?"
Robert Rossney

99
มันเป็นไวยากรณ์ที่น่ากลัว - สร้างภาษา Python ที่เลวร้ายที่สุดได้อย่างง่ายดายใกล้กับระดับความไร้สาระของ Perl ในการประเมินที่ไม่เป็นไปตามลำดับ - แต่มันเป็นสิ่งที่ถูกถาม คุณลงคะแนนอย่างจริงจังเพื่อหาคำตอบว่าถูกต้องหรือไม่
Glenn Maynard

41
มันเป็นคำตอบที่ถูกต้องสำหรับคำถามที่ว่า "ฉันจะเขียนฟังก์ชันแลมบ์ดาที่บอกฉันได้อย่างไรว่าตัวเลขมีค่าเท่ากัน?" อย่างไรก็ตามมันไม่ได้เป็นคำตอบที่ถูกต้องสำหรับคำถามที่ OP ได้ถามมา แต่ที่คุณไม่ได้เหมือนเช่นที่ผมวางแผนไว้โพสต์ของฉันไม่ในความเป็นจริงที่จะตอบคำถามของ OP ได้อย่างชัดเจน
Robert Rossney

10
เห็นได้ชัดว่าเจ็บปวดใครก็ตามที่แนะนำ "x% 2 == 0" - หรือโหวตความคิดเห็นที่แนะนำซึ่งทำให้คนอย่างน้อยเจ็ดคน - ไม่ได้อ่านคำถามต้นฉบับ
Glenn Maynard

40

ทำไมคุณไม่กำหนดฟังก์ชั่น?

def f(x):
    if x == 2:
        print(x)
    else:
        raise ValueError

ไม่มีเหตุผลที่แท้จริงที่จะใช้แลมบ์ดาในกรณีนี้


3
printยังไม่มีฟังก์ชั่นใน 2.6 :)
LukášLalinský

7
@ LukášLalinský: มันยังใช้งานได้ใน 2.x ก็จะถือว่าเป็นคู่ของวงเล็บซ้ำซ้อน
newacct

24
คุณไม่รู้กรณีการใช้งานจริงของเขาดังนั้นจึงไม่มีทางที่คุณจะพูดได้ว่าไม่มีเหตุผลที่จะต้องใช้แลมบ์ดา
Glenn Maynard

6
@Glenn Maynard: แทบจะไม่มีเหตุผลที่จะใช้แลมบ์ดา การกำหนดแลมบ์ดาให้กับตัวแปร - เป็นแบบสแตนด์อะโลนสำหรับdef- โดยทั่วไปแล้วเป็นความคิดที่แย่มาก (tm) เพียงแค่ใช้defโปรแกรมเมอร์ผู้ตายเท่านั้นที่สามารถอ่านตีความเข้าใจและดูแลรักษาได้
S.Lott

17
มีการใช้แลมบ์ดาอย่างถูกกฎหมาย หากคุณไม่สามารถคิดอะไรได้นั่นก็ไม่ใช่ความผิดของแลมบ์ดา (ฉันไม่ได้เป็นแฟนของไวยากรณ์ตัวเองแน่นอน - มันเป็นวิธีแก้ปัญหาเงอะงะความจริงที่ว่างูใหญ่ไม่ดีรู้สึกเยื้องไวยากรณ์ไม่สามารถจัดการกับฟังก์ชั่นแบบอินไลน์เช่นภาษาปกติ.)
เกล็นเมย์นาร์

25

อาจเป็นงูหลามที่แย่ที่สุดที่ฉันเคยเขียน:

f = lambda x: sys.stdout.write(["2\n",][2*(x==2)-2])

ถ้า x == 2 คุณพิมพ์

ถ้า x! = 2 คุณเพิ่ม


รุ่งโรจน์ฉันคิดว่านี่เป็นคำตอบเดียวในหน้าเว็บที่ตอบคำถามจริง
theEpsilon

22

คุณสามารถยกข้อยกเว้นได้อย่างง่ายดายในแลมบ์ดาถ้านั่นคือสิ่งที่คุณต้องการทำ

def Raise(exception):
    raise exception
x = lambda y: 1 if y < 2 else Raise(ValueError("invalid value"))

นี่เป็นความคิดที่ดีหรือไม่? สัญชาตญาณของฉันโดยทั่วไปคือการทิ้งข้อผิดพลาดในการรายงานจาก lambdas; ปล่อยให้มันมีค่าเป็นไม่มีและเพิ่มข้อผิดพลาดในการโทร ฉันไม่คิดว่านี่เป็นสิ่งที่ชั่วร้าย แต่ฉันคิดว่า "y if x else z" นั้นเลวร้ายยิ่งกว่าเดิม - ตรวจสอบให้แน่ใจว่าคุณไม่ได้พยายามยัดของแลมบ์ดามากเกินไป


1
เพิ่มมันในผู้โทรอาจเป็นวิธีที่ดีกว่าถ้าคุณถามฉัน
Dominic Bou-Samra

อาจเป็นไปได้ แต่มันขึ้นอยู่กับกรณีเฉพาะ แน่นอนคุณยังสามารถตกแต่งแลมด้าได้หลังจากสร้างมันขึ้นมา x = RaiseValueErrorOnNone(x)อีกครั้งขึ้นอยู่กับกรณี
Glenn Maynard

15

Lambdas ใน Python ค่อนข้างเข้มงวดเกี่ยวกับสิ่งที่คุณได้รับอนุญาตให้ใช้ โดยเฉพาะคุณไม่สามารถมีคำหลักใด ๆ (ยกเว้นสำหรับผู้ประกอบการเช่นand, not,orฯลฯ ) ในร่างกายของพวกเขา

ดังนั้นจึงไม่มีวิธีที่คุณสามารถใช้แลมบ์ดาสำหรับตัวอย่างของคุณ (เพราะคุณไม่สามารถใช้raise) แต่ถ้าคุณยินดีที่จะยอมรับในเรื่องนั้น ... คุณสามารถใช้:

f = lambda x: x == 2 and x or None

16
ข้อ จำกัด เฉพาะของแลมบ์ดาคือคุณไม่ได้รับอนุญาตให้ใช้คำสั่งเฉพาะการแสดงออก
Daniel Werner

13

ทราบว่าคุณสามารถใช้อื่น ๆ ... ถ้างบในคำนิยามแลมบ์ดาของคุณ:

f = lambda x: 1 if x>0 else 0 if x ==0 else -1

2

หากคุณยังคงต้องการพิมพ์คุณสามารถนำเข้าโมดูลในอนาคต

from __future__ import print_function

f = lambda x: print(x) if x%2 == 0 else False

2

คุณยังสามารถใช้ตัวดำเนินการทางลอจิคัลเพื่อมีเงื่อนไขเช่น

func = lambda element: (expression and DoSomething) or DoSomethingIfExpressionIsFalse

คุณสามารถดูข้อมูลเพิ่มเติมเกี่ยวกับผู้ประกอบการทางตรรกะได้ที่นี่


มันไม่สอดคล้องกับปรัชญาของงูใหญ่ในแง่ของความชัดเจน แม้ว่าจะเทียบเท่าในเชิงตรรกะ แต่ifไวยากรณ์ก็ยังดีกว่า ที่เห็นได้ชัดวิธีการตรวจสอบเงื่อนไข
0xc0de

ขอบคุณ! ผมใช้วิธีนี้ในการทำงานของภาษาการทำงานในวิทยาลัยเนื่องจากข้อ จำกัด ที่อาจารย์ได้กำหนดที่บอกว่าฉันไม่สามารถใช้ifคำสั่งเพื่อให้ฉันพบนี้ไม่ชัดเจนทาง
Victor Lucas

2

สิ่งที่คุณต้องการคือ

def fun():
    raise Exception()
f = lambda x:print x if x==2 else fun()

ตอนนี้เรียกใช้ฟังก์ชันในแบบที่คุณต้องการ

f(2)
f(3)


0

รหัสตัวอย่างต่อไปนี้ใช้งานได้สำหรับฉัน ไม่แน่ใจว่าเกี่ยวข้องโดยตรงกับคำถามนี้หรือไม่ แต่หวังว่าจะช่วยได้ในบางกรณี

a = ''.join(map(lambda x: str(x*2) if x%2==0 else "", range(10)))


0

วิธีง่ายๆในการดำเนินการถ้าในแลมบ์ดาคือการใช้รายการความเข้าใจ

คุณไม่สามารถยกข้อยกเว้นในแลมบ์ดาได้ แต่นี่เป็นวิธีใน Python 3.x เพื่อทำบางสิ่งที่ใกล้เคียงกับตัวอย่างของคุณ:

f = lambda x: print(x) if x==2 else print("exception")

ตัวอย่างอื่น:

ส่งคืน 1 ถ้า M เป็นอย่างอื่น 0

f = lambda x: 1 if x=="M" else 0
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.