Python สนับสนุนการลัดวงจรในนิพจน์บูลีนหรือไม่?
Python สนับสนุนการลัดวงจรในนิพจน์บูลีนหรือไม่?
คำตอบ:
and
, or
:ก่อนอื่นเรามากำหนดฟังก์ชั่นที่มีประโยชน์เพื่อพิจารณาว่ามีการดำเนินการบางอย่างหรือไม่ ฟังก์ชั่นง่าย ๆ ที่ยอมรับการโต้แย้งพิมพ์ข้อความและส่งกลับค่าไม่เปลี่ยนแปลง
>>> def fun(i):
... print "executed"
... return i
...
หนึ่งสามารถสังเกตพฤติกรรมการลัดวงจร- ธของand
, or
ผู้ประกอบการในตัวอย่างต่อไปนี้:
>>> fun(1)
executed
1
>>> 1 or fun(1) # due to short-circuiting "executed" not printed
1
>>> 1 and fun(1) # fun(1) called and "executed" printed
executed
1
>>> 0 and fun(1) # due to short-circuiting "executed" not printed
0
หมายเหตุ:ค่าต่อไปนี้ถูกพิจารณาโดยล่ามเพื่อหมายถึงเท็จ:
False None 0 "" () [] {}
any()
, all()
:งูหลามany()
และall()
ฟังก์ชั่นยังรองรับการลัดวงจร ตามที่แสดงในเอกสาร; พวกเขาประเมินแต่ละองค์ประกอบของลำดับตามลำดับจนกระทั่งพบผลลัพธ์ที่อนุญาตให้ออกก่อนกำหนดในการประเมินผล พิจารณาตัวอย่างด้านล่างเพื่อทำความเข้าใจทั้งสองอย่าง
ฟังก์ชั่นany()
ตรวจสอบว่าองค์ประกอบใด ๆ เป็นจริง มันจะหยุดดำเนินการทันทีที่พบ True และส่งคืน True
>>> any(fun(i) for i in [1, 2, 3, 4]) # bool(1) = True
executed
True
>>> any(fun(i) for i in [0, 2, 3, 4])
executed # bool(0) = False
executed # bool(2) = True
True
>>> any(fun(i) for i in [0, 0, 3, 4])
executed
executed
executed
True
ฟังก์ชั่นall()
ตรวจสอบองค์ประกอบทั้งหมดเป็นจริงและหยุดดำเนินการทันทีที่พบเท็จ:
>>> all(fun(i) for i in [0, 0, 3, 4])
executed
False
>>> all(fun(i) for i in [1, 0, 3, 4])
executed
executed
False
นอกจากนี้ใน Python
การเปรียบเทียบสามารถถูกล่ามโซ่โดยพลการ ; ตัวอย่างเช่น
x < y <= z
เทียบเท่าx < y and y <= z
ยกเว้นที่y
ประเมินเพียงครั้งเดียว (แต่ในทั้งสองกรณีz
ไม่ได้รับการประเมินเลยเมื่อx < y
พบว่าเป็นเท็จ)
>>> 5 > 6 > fun(3) # same as: 5 > 6 and 6 > fun(3)
False # 5 > 6 is False so fun() not called and "executed" NOT printed
>>> 5 < 6 > fun(3) # 5 < 6 is True
executed # fun(3) called and "executed" printed
True
>>> 4 <= 6 > fun(7) # 4 <= 6 is True
executed # fun(3) called and "executed" printed
False
>>> 5 < fun(6) < 3 # only prints "executed" once
executed
False
>>> 5 < fun(6) and fun(6) < 3 # prints "executed" twice, because the second part executes it again
executed
executed
False
แก้ไข:
จุดหนึ่งที่น่าสนใจมากขึ้นที่จะต้องทราบ: -ตรรกะand
,or
ผู้ประกอบการในหลามผลตอบแทนของตัวถูกดำเนินการค่าแทนการบูลีน ( True
หรือFalse
) ตัวอย่างเช่น:
การดำเนินการ
x and y
ให้ผลลัพธ์if x is false, then x, else y
ซึ่งแตกต่างจากในภาษาอื่น ๆ เช่น&&
, ||
ผู้ประกอบการในซีที่ผลตอบแทน 0 หรือ 1
ตัวอย่าง:
>>> 3 and 5 # Second operand evaluated and returned
5
>>> 3 and ()
()
>>> () and 5 # Second operand NOT evaluated as first operand () is false
() # so first operand returned
or
ผู้ประกอบการในทำนองเดียวกันกลับเหลือค่ามากที่สุดซึ่งbool(value)
==True
อื่นที่เหมาะสมมูลค่าเท็จมากที่สุด (ตามพฤติกรรมการลัดวงจร) ตัวอย่าง:
>>> 2 or 5 # left most operand bool(2) == True
2
>>> 0 or 5 # bool(0) == False and bool(5) == True
5
>>> 0 or ()
()
ดังนั้นสิ่งนี้มีประโยชน์อย่างไร? หนึ่งใช้ตัวอย่างที่ได้รับในการปฏิบัติหลามโดยแมกนัสโกหก Hetland:
สมมติว่าผู้ใช้ควรจะใส่ชื่อของเขาหรือเธอ '<unknown>'
แต่อาจเลือกที่จะใส่อะไรซึ่งในกรณีที่คุณต้องการใช้ค่าเริ่มต้น คุณสามารถใช้คำสั่ง if แต่คุณยังสามารถระบุสิ่งที่รัดกุมมาก:
In [171]: name = raw_input('Enter Name: ') or '<Unkown>'
Enter Name:
In [172]: name
Out[172]: '<Unkown>'
กล่าวอีกนัยหนึ่งถ้าค่าส่งคืนจาก raw_input เป็นจริง (ไม่ใช่สตริงว่าง) จะถูกกำหนดเป็นชื่อ (ไม่มีการเปลี่ยนแปลง) มิฉะนั้นเริ่มต้นได้รับมอบหมายให้'<unknown>'
name
0
เป็น falsy (ดังนั้นจึงไม่ได้เป็นเพียง0
ก็0.0
, 0j
, decimal.Decimal(0)
, fractions.Fraction(0)
ฯลฯ ) เช่นเดียวกับคอลเลกชันทั้งหมดที่มีความยาว0
(เพื่อให้อยู่ด้านบนของสิ่งที่คุณอยู่ในรายการb''
[Py3] u''
[Py2] และset()
/ frozenset()
มี บิวด์อินทั้งหมดที่ประเมินว่าเป็นเท็จ) แต่ผู้ใช้กำหนดเอง / บุคคลที่สามสามารถกำหนดประเภทของตนเอง (ด้วย__bool__
[Py3] / __nonzero__
[Py2] โดยตรงหรือโดยอ้อมโดยการกำหนด__len__
)
ใช่. ลองต่อไปนี้ในตัวแปลของหลาม:
และ
>>>False and 3/0
False
>>>True and 3/0
ZeroDivisionError: integer division or modulo by zero
หรือ
>>>True or 3/0
True
>>>False or 3/0
ZeroDivisionError: integer division or modulo by zero