ฉันได้รับข้อผิดพลาดในเงื่อนไข IF ผมทำอะไรผิดหรือเปล่า?
มีเหตุผลที่คุณได้รับSyntaxError
คือไม่มี&&
ตัวดำเนินการใน Python ในทำนองเดียวกัน||
และ!
มีความไม่ถูกต้องผู้ประกอบการหลาม
ตัวดำเนินการบางอย่างที่คุณอาจรู้จักจากภาษาอื่นมีชื่อแตกต่างกันใน Python ผู้ประกอบการเชิงตรรกะ&&
และ||
จะเรียกว่าจริงและand
or
ในทำนองเดียวกันผู้ประกอบการปฏิเสธตรรกะที่เรียกว่า!
not
ดังนั้นคุณสามารถเขียน:
if len(a) % 2 == 0 and len(b) % 2 == 0:
หรือแม้กระทั่ง:
if not (len(a) % 2 or len(b) % 2):
ข้อมูลเพิ่มเติมบางอย่าง (ที่อาจมีประโยชน์):
ฉันสรุปผู้ประกอบการ "เทียบเท่า" ในตารางนี้:
+------------------------------+---------------------+
| Operator (other languages) | Operator (Python) |
+==============================+=====================+
| && | and |
+------------------------------+---------------------+
| || | or |
+------------------------------+---------------------+
| ! | not |
+------------------------------+---------------------+
ดูเอกสารประกอบของ Python: 6.11 ดำเนินการบูลี
นอกจากตัวดำเนินการเชิงตรรกะ Python ยังมีตัวดำเนินการ bitwise / binary:
+--------------------+--------------------+
| Logical operator | Bitwise operator |
+====================+====================+
| and | & |
+--------------------+--------------------+
| or | | |
+--------------------+--------------------+
ไม่มีการปฏิเสธบิตในหลามเป็น (เพียงบิตผกผันผู้ประกอบการ~
- แต่ที่ไม่เทียบเท่าnot
)
ดูเพิ่มเติมที่6.6 เลขคณิต Unary และการดำเนินการระดับบิต / ไบนารีและ6.7 การดำเนินการทางเลขฐานสอง
ตัวดำเนินการเชิงตรรกะ (เหมือนในภาษาอื่น ๆ ) มีข้อได้เปรียบที่สิ่งเหล่านี้จะลัดวงจร นั่นหมายความว่าถ้าตัวถูกดำเนินการตัวแรกกำหนดผลลัพธ์ไว้ผู้ดำเนินการรายที่สองจะไม่ได้รับการประเมินเลย
เพื่อแสดงสิ่งนี้ฉันใช้ฟังก์ชั่นที่รับค่าเพียงพิมพ์และส่งคืนอีกครั้ง สิ่งนี้มีประโยชน์ในการดูสิ่งที่ประเมินผลจริงเนื่องจากข้อความสั่งพิมพ์:
>>> def print_and_return(value):
... print(value)
... return value
>>> res = print_and_return(False) and print_and_return(True)
False
อย่างที่คุณเห็นเพียงคำสั่งการพิมพ์เพียงคำสั่งเดียวดังนั้น Python จึงไม่ได้ดูตัวถูกดำเนินการที่ถูกต้องจริงๆ
นี่ไม่ใช่กรณีสำหรับตัวดำเนินการไบนารี ผู้ประเมินทั้งสองตัวถูกดำเนินการเสมอ:
>>> res = print_and_return(False) & print_and_return(True);
False
True
แต่ถ้าตัวถูกดำเนินการตัวแรกนั้นไม่เพียงพอแน่นอนตัวดำเนินการที่สองจะถูกประเมิน:
>>> res = print_and_return(True) and print_and_return(False);
True
False
เพื่อสรุปนี่คือตารางอื่น:
+-----------------+-------------------------+
| Expression | Right side evaluated? |
+=================+=========================+
| `True` and ... | Yes |
+-----------------+-------------------------+
| `False` and ... | No |
+-----------------+-------------------------+
| `True` or ... | No |
+-----------------+-------------------------+
| `False` or ... | Yes |
+-----------------+-------------------------+
True
และFalse
เป็นตัวแทนของสิ่งbool(left-hand-side)
ตอบแทนที่พวกเขาไม่จำเป็นต้องเป็นTrue
หรือFalse
พวกเขาเพียงต้องการที่จะกลับมาTrue
หรือFalse
เมื่อbool
มีการเรียกร้องให้พวกเขา (1)
ดังนั้นใน Pseudo-Code (!) and
และor
ฟังก์ชั่นทำงานเช่นนี้
def and(expr1, expr2):
left = evaluate(expr1)
if bool(left):
return evaluate(expr2)
else:
return left
def or(expr1, expr2):
left = evaluate(expr1)
if bool(left):
return left
else:
return evaluate(expr2)
โปรดทราบว่านี่เป็นรหัสหลอกไม่ใช่รหัสงูหลาม ใน Python คุณไม่สามารถสร้างฟังก์ชั่นที่เรียกว่าand
หรือor
เพราะสิ่งเหล่านี้เป็นคำหลัก นอกจากนี้คุณไม่ควรใช้ "ประเมิน" if bool(...)
หรือ
การปรับพฤติกรรมของชั้นเรียนของคุณเอง
นี้โดยปริยายbool
โทรสามารถใช้ในการกำหนดวิธีการเรียนของคุณประพฤติด้วยand
, และor
not
เพื่อแสดงให้เห็นว่าสิ่งนี้สามารถปรับแต่งได้ฉันใช้คลาสนี้ซึ่งprint
เป็นสิ่งที่ติดตามสิ่งที่เกิดขึ้นอีกครั้ง:
class Test(object):
def __init__(self, value):
self.value = value
def __bool__(self):
print('__bool__ called on {!r}'.format(self))
return bool(self.value)
__nonzero__ = __bool__ # Python 2 compatibility
def __repr__(self):
return "{self.__class__.__name__}({self.value})".format(self=self)
ดังนั้นเรามาดูกันว่าจะเกิดอะไรขึ้นกับคลาสนั้นร่วมกับโอเปอเรเตอร์เหล่านี้:
>>> if Test(True) and Test(False):
... pass
__bool__ called on Test(True)
__bool__ called on Test(False)
>>> if Test(False) or Test(False):
... pass
__bool__ called on Test(False)
__bool__ called on Test(False)
>>> if not Test(True):
... pass
__bool__ called on Test(True)
ถ้าคุณไม่มี__bool__
เมธอดแล้ว Python จะตรวจสอบว่าวัตถุนั้นมี__len__
เมธอดหรือไม่และส่งคืนค่าที่มากกว่าศูนย์หรือไม่ อาจเป็นประโยชน์ที่จะรู้ในกรณีที่คุณสร้างคอนเทนเนอร์ตามลำดับ
ดูเพิ่มเติม4.1 ความจริงการทดสอบราคา
NumPy อาร์เรย์และคลาสย่อย
อาจจะเกินขอบเขตของคำถามเดิมเล็กน้อย แต่ในกรณีที่คุณติดต่อกับ NumPy อาร์เรย์หรือคลาสย่อย (เช่น Pandas Series หรือ DataFrames) การbool
โทรโดยนัยจะเพิ่มความน่ากลัวValueError
:
>>> import numpy as np
>>> arr = np.array([1,2,3])
>>> bool(arr)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> arr and arr
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> import pandas as pd
>>> s = pd.Series([1,2,3])
>>> bool(s)
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> s and s
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
ในกรณีเหล่านี้คุณสามารถใช้ตรรกะและฟังก์ชั่นจาก NumPy ซึ่งดำเนินการองค์ประกอบที่ชาญฉลาดand
(หรือor
):
>>> np.logical_and(np.array([False,False,True,True]), np.array([True, False, True, False]))
array([False, False, True, False])
>>> np.logical_or(np.array([False,False,True,True]), np.array([True, False, True, False]))
array([ True, False, True, True])
หากคุณกำลังจัดการกับบูลีนอาร์เรย์คุณสามารถใช้ตัวดำเนินการไบนารีกับ NumPy สิ่งเหล่านี้ทำการเปรียบเทียบองค์ประกอบที่ฉลาด (แต่ยังเป็นไบนารี):
>>> np.array([False,False,True,True]) & np.array([True, False, True, False])
array([False, False, True, False])
>>> np.array([False,False,True,True]) | np.array([True, False, True, False])
array([ True, False, True, True])
(1)
การbool
เรียกใช้ตัวถูกดำเนินการต้องส่งคืนTrue
หรือFalse
ไม่ถูกต้องอย่างสมบูรณ์ มันเป็นเพียงตัวถูกดำเนินการแรกที่ต้องการคืนค่าบูลีนด้วย__bool__
วิธี:
class Test(object):
def __init__(self, value):
self.value = value
def __bool__(self):
return self.value
__nonzero__ = __bool__ # Python 2 compatibility
def __repr__(self):
return "{self.__class__.__name__}({self.value})".format(self=self)
>>> x = Test(10) and Test(10)
TypeError: __bool__ should return bool, returned int
>>> x1 = Test(True) and Test(10)
>>> x2 = Test(False) and Test(10)
นั่นเป็นเพราะand
จริง ๆ แล้วคืนค่าตัวถูกดำเนินการแรกถ้าตัวถูกดำเนินการตัวแรกประเมินค่าFalse
และถ้าประเมินตัวถูกTrue
แล้วมันส่งคืนตัวถูกดำเนินการตัวที่สอง:
>>> x1
Test(10)
>>> x2
Test(False)
ในทำนองเดียวกันสำหรับor
วิธีอื่น ๆ :
>>> Test(True) or Test(10)
Test(True)
>>> Test(False) or Test(10)
Test(10)
อย่างไรก็ตามหากคุณใช้พวกเขาในif
คำแถลงif
ก็จะเรียกbool
ผลลัพธ์โดยปริยาย ดังนั้นคะแนนปลีกย่อยเหล่านี้อาจไม่เกี่ยวข้องกับคุณ