Tôi đang gặp lỗi trong điều kiện IF. Tôi đang làm gì sai?
Có một lý do mà bạn nhận được SyntaxError
là không có &&
toán tử nào trong Python. Tương tự như vậy ||
và không phải!
là toán tử Python hợp lệ .
Một số toán tử bạn có thể biết từ các ngôn ngữ khác có tên khác trong Python. Các toán tử logic &&
và ||
thực sự được gọi and
và or
. Tương tự như vậy, toán tử phủ định logic !
được gọi not
.
Vì vậy, bạn chỉ có thể viết:
if len(a) % 2 == 0 and len(b) % 2 == 0:
hoặc thậm chí:
if not (len(a) % 2 or len(b) % 2):
Một số thông tin bổ sung (có thể có ích):
Tôi đã tóm tắt toán tử "tương đương" trong bảng này:
+------------------------------+---------------------+
| Operator (other languages) | Operator (Python) |
+==============================+=====================+
| && | and |
+------------------------------+---------------------+
| || | or |
+------------------------------+---------------------+
| ! | not |
+------------------------------+---------------------+
Xem thêm tài liệu Python: 6.11. Hoạt động Boolean .
Bên cạnh các toán tử logic, Python cũng có các toán tử bitwise / binary:
+--------------------+--------------------+
| Logical operator | Bitwise operator |
+====================+====================+
| and | & |
+--------------------+--------------------+
| or | | |
+--------------------+--------------------+
Không có phủ định bitwise trong Python (chỉ là toán tử nghịch đảo bitwise ~
- nhưng điều đó không tương đương với not
).
Xem thêm 6.6. Số học đơn phương và các phép toán bitwise / binary và 6.7. Phép toán số học nhị phân .
Các toán tử logic (như trong nhiều ngôn ngữ khác) có lợi thế là chúng được ngắn mạch. Điều đó có nghĩa là nếu toán hạng thứ nhất đã xác định kết quả, thì toán tử thứ hai hoàn toàn không được đánh giá.
Để hiển thị điều này, tôi sử dụng một hàm chỉ đơn giản là lấy một giá trị, in nó và trả lại nó. Điều này rất hữu ích để xem những gì thực sự được đánh giá vì các báo cáo in:
>>> def print_and_return(value):
... print(value)
... return value
>>> res = print_and_return(False) and print_and_return(True)
False
Như bạn có thể thấy chỉ có một câu lệnh in được thực thi, do đó Python thực sự thậm chí không nhìn vào toán hạng đúng.
Đây không phải là trường hợp cho các toán tử nhị phân. Những người luôn đánh giá cả hai toán hạng:
>>> res = print_and_return(False) & print_and_return(True);
False
True
Nhưng nếu toán hạng thứ nhất không đủ thì dĩ nhiên, toán tử thứ hai được ước tính:
>>> res = print_and_return(True) and print_and_return(False);
True
False
Để tóm tắt đây là một Bảng khác:
+-----------------+-------------------------+
| Expression | Right side evaluated? |
+=================+=========================+
| `True` and ... | Yes |
+-----------------+-------------------------+
| `False` and ... | No |
+-----------------+-------------------------+
| `True` or ... | No |
+-----------------+-------------------------+
| `False` or ... | Yes |
+-----------------+-------------------------+
Các True
và False
đại diện cho những gì bool(left-hand-side)
lợi nhuận, họ không phải là True
hay False
, họ chỉ cần phải trả lại True
hoặc False
khi bool
được gọi vào chúng (1).
Vì vậy, trong Mã giả (!), and
Và các or
hàm hoạt động như sau:
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)
Lưu ý rằng đây là mã giả chứ không phải mã Python. Trong Python bạn không thể tạo các hàm được gọi and
hoặc or
vì đây là các từ khóa. Ngoài ra, bạn không bao giờ nên sử dụng "đánh giá" hoặc if bool(...)
.
Tùy chỉnh hành vi của các lớp của riêng bạn
Tiềm ẩn này bool
cuộc gọi có thể được sử dụng để tùy chỉnh cách lớp học của bạn cư xử với and
, or
và not
.
Để chỉ ra làm thế nào điều này có thể được tùy chỉnh, tôi sử dụng lớp này một lần nữa print
để theo dõi những gì đang xảy ra:
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)
Vì vậy, hãy xem điều gì xảy ra với lớp đó kết hợp với các toán tử này:
>>> 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)
Nếu bạn không có __bool__
phương thức thì Python cũng kiểm tra xem đối tượng có __len__
phương thức không và liệu nó có trả về giá trị lớn hơn không. Điều đó có thể hữu ích để biết trong trường hợp bạn tạo một thùng chứa trình tự.
Xem thêm 4.1. Kiểm tra giá trị thật .
Mảng NumPy và các lớp con
Có thể vượt quá phạm vi của câu hỏi ban đầu nhưng trong trường hợp bạn đang xử lý các mảng NumPy hoặc các lớp con (như Pandas Series hoặc DataFrames) thì bool
cuộc gọi ngầm sẽ gây ra sự sợ hãi 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().
Trong những trường hợp này, bạn có thể sử dụng logic và hàm từ NumPy để thực hiện phần tử and
(hoặc 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])
Nếu bạn đang xử lý chỉ với các mảng boolean, bạn cũng có thể sử dụng các toán tử nhị phân với NumPy, chúng thực hiện các phép so sánh phần tử (nhưng cũng là nhị phân):
>>> 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)
Cuộc bool
gọi trên toán hạng phải trả về True
hoặc False
không hoàn toàn chính xác. Đây chỉ là toán hạng đầu tiên cần trả về boolean trong __bool__
phương thức của nó :
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)
Đó là bởi vì and
thực sự trả về toán hạng đầu tiên nếu toán hạng thứ nhất ước lượng False
và nếu nó ước lượng True
thì nó trả về toán hạng thứ hai:
>>> x1
Test(10)
>>> x2
Test(False)
Tương tự như vậy or
nhưng chỉ là cách khác:
>>> Test(True) or Test(10)
Test(True)
>>> Test(False) or Test(10)
Test(10)
Tuy nhiên, nếu bạn sử dụng chúng trong một if
tuyên bố, if
nó cũng sẽ ngầm gọi bool
kết quả. Vì vậy, những điểm tốt hơn có thể không phù hợp với bạn.