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 SyntaxErrorlà 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 andvà 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 Truevà Falseđại diện cho những gì bool(left-hand-side)lợi nhuận, họ không phải là Truehay False, họ chỉ cần phải trả lại Truehoặc Falsekhi boolđược gọi vào chúng (1).
Vì vậy, trong Mã giả (!), andVà các orhà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 andhoặc orvì đâ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 boolcuộ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, orvà 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ì boolcuộ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 boolgọi trên toán hạng phải trả về Truehoặc Falsekhô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ì andthực sự trả về toán hạng đầu tiên nếu toán hạng thứ nhất ước lượng Falsevà nếu nó ước lượng Truethì nó trả về toán hạng thứ hai:
>>> x1
Test(10)
>>> x2
Test(False)
Tương tự như vậy ornhư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 iftuyên bố, ifnó cũng sẽ ngầm gọi boolkết quả. Vì vậy, những điểm tốt hơn có thể không phù hợp với bạn.