TL; ดร
เราเริ่มต้นด้วยการสรุปพฤติกรรมสองอย่างของตัวดำเนินการตรรกะสองตัวand
และor
. สำนวนเหล่านี้จะเป็นพื้นฐานของการสนทนาด้านล่าง
and
ส่งคืนค่า Falsy แรกหากมีไม่เช่นนั้นจะส่งคืนค่าสุดท้ายในนิพจน์
or
ส่งคืนค่า Truthy แรกหากมีค่าอื่นส่งคืนค่าสุดท้ายในนิพจน์
นอกจากนี้ยังสรุปพฤติกรรมในเอกสารโดยเฉพาะในตารางนี้:
ตัวดำเนินการเดียวที่ส่งคืนค่าบูลีนโดยไม่คำนึงถึงตัวถูกดำเนินการคือตัวดำเนินnot
การ
"ความจริง" และการประเมิน "ความจริง"
คำสั่ง
len(args) and max(args) - min(args)
เป็นมาก pythonicรัดกุม (และเนื้อหาที่อ่านได้น้อยลง) วิธีการพูดว่า "ถ้าargs
ไม่ว่างกลับผลมาจากmax(args) - min(args)
" 0
มิฉะนั้นผลตอบแทน โดยทั่วไปแล้วเป็นการif-else
แสดงนิพจน์ที่กระชับมากขึ้น ตัวอย่างเช่น,
exp1 and exp2
ควร (โดยประมาณ) แปลเป็น:
r1 = exp1
if r1:
r1 = exp2
หรือเทียบเท่า
r1 = exp2 if exp1 else exp1
ในทำนองเดียวกัน
exp1 or exp2
ควร (โดยประมาณ) แปลเป็น:
r1 = exp1
if not r1:
r1 = exp2
หรือเทียบเท่า
r1 = exp1 if exp1 else exp2
วัตถุ python ที่กำหนดเองexp1
และอยู่ที่ไหนexp2
หรือนิพจน์ที่ส่งคืนวัตถุ กุญแจสำคัญในการทำความเข้าใจการใช้งานของตรรกะand
และor
ตัวดำเนินการในที่นี้คือการทำความเข้าใจว่าพวกเขาไม่ได้ถูก จำกัด ให้ทำงานบนหรือส่งคืนค่าบูลีน สามารถทดสอบวัตถุใด ๆ ที่มีค่าความจริงได้ที่นี่ ซึ่งรวมถึงint
, str
, list
, dict
, tuple
, set
, NoneType
วัตถุและผู้ใช้กำหนด กฎการลัดวงจรยังคงมีผลบังคับใช้เช่นกัน
แต่ความจริงคืออะไร?
หมายถึงวิธีการประเมินวัตถุเมื่อใช้ในนิพจน์เงื่อนไข @Patrick Haugh สรุปความจริงไว้ในโพสต์นี้
ค่าทั้งหมดถือเป็น "จริง" ยกเว้นค่าต่อไปนี้ซึ่งเป็น "เท็จ":
None
False
0
0.0
0j
Decimal(0)
Fraction(0, 1)
[]
- ว่างเปล่า list
{}
- ว่างเปล่า dict
()
- ว่างเปล่า tuple
''
- ว่างเปล่า str
b''
- ว่างเปล่า bytes
set()
- ว่างเปล่า set
- ว่างเปล่า
range
เช่นrange(0)
- วัตถุที่
obj.__bool__()
ผลตอบแทน False
obj.__len__()
ผลตอบแทน 0
ค่า "จริง" จะตอบสนองการตรวจสอบที่ดำเนินการโดยif
หรือwhile
คำสั่ง เราใช้ "truthy" และ "falsy" เพื่อให้แตกต่างจาก
bool
ค่าและTrue
False
วิธีการand
ทำงาน
เราสร้างคำถามของ OP เพื่อต่อยอดในการอภิปรายเกี่ยวกับวิธีการที่ตัวดำเนินการเหล่านี้ในกรณีเหล่านี้
กำหนดฟังก์ชันพร้อมนิยาม
def foo(*args):
...
ฉันจะคืนค่าความแตกต่างระหว่างค่าต่ำสุดและค่าสูงสุดในรายการอาร์กิวเมนต์เป็นศูนย์หรือมากกว่าได้อย่างไร
การหาค่าต่ำสุดและสูงสุดเป็นเรื่องง่าย (ใช้ฟังก์ชัน inbuilt!) อุปสรรคเดียวที่นี่คือการจัดการกรณีมุมอย่างเหมาะสมซึ่งรายการอาร์กิวเมนต์อาจว่างเปล่า (เช่นการโทรfoo()
) เราสามารถทำได้ทั้งสองบรรทัดในบรรทัดเดียวด้วยตัวand
ดำเนินการ:
def foo(*args):
return len(args) and max(args) - min(args)
foo(1, 2, 3, 4, 5)
foo()
นับตั้งแต่มีการใช้การแสดงออกที่สองยังต้องได้รับการประเมินถ้าแรกคือand
True
โปรดทราบว่าถ้าการแสดงออกครั้งแรกที่ได้รับการประเมินให้เป็น truthy ค่าส่งกลับเป็นเสมอผลของการแสดงออกที่สอง หากนิพจน์แรกได้รับการประเมินว่าเป็น Falsy ผลลัพธ์ที่ส่งกลับจะเป็นผลลัพธ์ของนิพจน์แรก
ในฟังก์ชั่นข้างต้นหากfoo
ได้รับหนึ่งหรือมากกว่าหนึ่งข้อโต้แย้งlen(args)
ที่มีค่ามากกว่า0
(เป็นจำนวนบวก) max(args) - min(args)
ดังนั้นผลลัพธ์ที่ปรากฏมี OTOH ถ้าข้อโต้แย้งไม่ได้ผ่านไปlen(args)
เป็น0
ซึ่งเป็น Falsy และ0
ถูกส่งกลับ
โปรดทราบว่าทางเลือกอื่นในการเขียนฟังก์ชันนี้คือ:
def foo(*args):
if not len(args):
return 0
return max(args) - min(args)
หรืออย่างรวบรัด
def foo(*args):
return 0 if not args else max(args) - min(args)
หากแน่นอนไม่มีฟังก์ชันเหล่านี้ทำการตรวจสอบประเภทใด ๆ ดังนั้นหากคุณไม่เชื่อถืออินพุตที่ให้มาอย่างสมบูรณ์อย่าพึ่งพาความเรียบง่ายของโครงสร้างเหล่านี้
วิธีการor
ทำงาน
ฉันอธิบายการทำงานor
ในลักษณะที่คล้ายกันพร้อมกับตัวอย่างที่สร้างขึ้น
กำหนดฟังก์ชันพร้อมนิยาม
def foo(*args):
...
คุณจะกรอกfoo
ตัวเลขทั้งหมดได้9000
อย่างไร?
เราใช้or
จับเคสเข้ามุมตรงนี้ เรากำหนดfoo
เป็น:
def foo(*args):
return [x for x in args if x > 9000] or 'No number over 9000!'
foo(9004, 1, 2, 500)
foo(1, 2, 3, 4)
foo
ทำการกรองในรายการเพื่อเก็บตัวเลขทั้งหมด9000
ไว้ หากมีตัวเลขดังกล่าวอยู่ผลลัพธ์ของความเข้าใจในรายการจะเป็นรายการที่ไม่ว่างเปล่าซึ่งเป็นความจริงดังนั้นจึงถูกส่งกลับ (การดำเนินการลัดวงจรที่นี่) หากไม่มีตัวเลขดังกล่าวผลลัพธ์ของคอมพ์รายการจะ[]
เป็น Falsy ดังนั้นนิพจน์ที่สองจึงได้รับการประเมินแล้ว (สตริงที่ไม่ว่างเปล่า) และถูกส่งกลับ
เมื่อใช้เงื่อนไขเราสามารถเขียนฟังก์ชันนี้ใหม่เป็น
def foo(*args):
r = [x for x in args if x > 9000]
if not r:
return 'No number over 9000!'
return r
ก่อนหน้านี้โครงสร้างนี้มีความยืดหยุ่นมากขึ้นในแง่ของการจัดการข้อผิดพลาด
and
(เช่นเดียวกับor
) ไม่ จำกัด เฉพาะการทำงานกับหรือส่งคืนค่าบูลีน