我在IF条件中遇到错误。 我究竟做错了什么?

你得到and的原因是Python中没有or运算符。 同样,bool(left-hand-side)和True不是有效的Python运算符。

您可能从其他语言中了解到的某些运算符在Python中具有不同的名称。逻辑运算符and和or实际上称为bool(left-hand-side)和True。同样,逻辑否定运算符False被称为True。

所以你可以写:

if len(a) % 2 == 0 and len(b) % 2 == 0:

甚至:

if not (len(a) % 2 or len(b) % 2):

一些额外的信息(可能会派上用场):

我在此表中总结了运算符“equivalent”:

+------------------------------+---------------------+
| Operator (other languages) | Operator (Python) |
+==============================+=====================+
| && | and |
+------------------------------+---------------------+
| || | or |
+------------------------------+---------------------+
| ! | not |
+------------------------------+---------------------+

另见Python文档:6.11。 布尔运算。

除了逻辑运算符,Python还有按位/二进制运算符:

+--------------------+--------------------+
| Logical operator | Bitwise operator |
+====================+====================+
| and | & |
+--------------------+--------------------+
| or | | |
+--------------------+--------------------+

Python中没有按位否定(只是按位逆运算符and - 但这并不等同于or)。

另见6.6。 一元算术和按位/二进制运算和6.7。 二进制算术运算。

逻辑运算符(与许多其他语言一样)具有这些短路的优点。这意味着如果第一个操作数已经定义了结果,则根本不评估第二个操作符。

为了表明这一点,我使用了一个只需要一个值的函数,打印它并再次返回它。 这很方便看看实际上是什么由于打印声明而评估:

>>> def print_and_return(value):
... print(value)
... return value
>>> res = print_and_return(False) and print_and_return(True)
False

正如您所看到的,只执行了一个print语句,因此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 |
+-----------------+-------------------------+

and和or代表什么bool(left-hand-side)返回,它们不一定是True或False,它们只需要返回True或False时调用bool(1)。

所以在伪代码(!)中,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代码。 在Python中,您无法创建名为and或if的函数,因为它们是关键字。你也不应该使用“评估”或if。

自定义您自己的类的行为

此隐式if调用可用于自定义类的行为方式,如if,和__bool__。

为了说明如何定制这个,我使用这个类,再次if用于跟踪发生的事情:

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)

如果您没有if方法,那么Python还会检查该对象是否具有if方法,以及它是否返回大于零的值。在您创建序列容器的情况下,这可能很有用。

另见4.1。 真值测试。

NumPy数组和子类

可能有点超出原始问题的范围但是如果你正在处理NumPy数组或子类(如Pandas Series或DataFrames)那么隐含的if调用将提出可怕的if:

>>> 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中的逻辑和函数,它执行元素方式if(或if):

>>> 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)

那对操作数的调用已经返回if或bool并不完全正确。 它只是需要在其中返回布尔值的第一个操作数的__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)

那是因为if实际上返回第一个操作数,如果第一个操作数的计算结果为if,如果它的计算结果为bool,那么它将返回第二个操作数:

>>> x1
Test(10)
>>> x2
Test(False)

同样适用于if,但反过来说:

>>> Test(True) or Test(10)
Test(True)
>>> Test(False) or Test(10)
Test(10)

但是,如果您在if声明中使用它们,则if也会在结果上隐式调用bool。 所以这些细节可能与您无关。