一般来说:
all 和 any 是接受一些可迭代并返回 True 的函数,如果
- 在
all() 的情况下,iterable 中没有任何值是虚假的;
- 在
any() 的情况下,至少有一个值为真。
如果bool(x) == False,则值x 是虚假的。
x 的值是真实的,如果 bool(x) == True。
iterable 中的任何非布尔值都可以——bool(x) 将根据以下规则映射(或强制,如果您愿意)任何 x:0、0.0、None、@987654336 @、()、[]、set() 和其他空集合映射到 False,其他任何东西都映射到 True。 bool 的文档字符串使用术语 'true'/'false' 表示 'truthy'/'falsy',True/False 表示具体的布尔值。
在您的特定代码示例中:
您对这些函数的工作方式有一点误解。因此,以下内容完全不是您想的那样:
if any(foobars) == big_foobar:
...因为any(foobars) 将首先被评估为True 或False,然后将该布尔值与big_foobar 进行比较,通常总是给你False(除非big_foobar碰巧是同一个布尔值)。
注意:可迭代对象可以是列表,但也可以是生成器/生成器表达式(≈ 延迟评估/生成的列表)或任何其他迭代器。
你想要的是:
if any(x == big_foobar for x in foobars):
它首先构造一个产生一系列布尔值的迭代器——对于foobars 中的每个项目,它会将项目与big_foobar 进行比较,并将结果布尔值发送到结果序列中:
tmp = (x == big_foobar for x in foobars)
然后any 遍历tmp 中的所有项目,并在找到第一个真实元素后立即返回True。就好像你做了以下事情:
In [1]: foobars = ['big', 'small', 'medium', 'nice', 'ugly']
In [2]: big_foobar = 'big'
In [3]: any(['big' == big_foobar, 'small' == big_foobar, 'medium' == big_foobar, 'nice' == big_foobar, 'ugly' == big_foobar])
Out[3]: True
注意:正如 DSM 指出的,any(x == y for x in xs) 等同于 y in xs,但后者更具可读性、编写速度更快、运行速度更快。
一些例子:
In [1]: any(x > 5 for x in range(4))
Out[1]: False
In [2]: all(isinstance(x, int) for x in range(10))
Out[2]: True
In [3]: any(x == 'Erik' for x in ['Erik', 'John', 'Jane', 'Jim'])
Out[3]: True
In [4]: all([True, True, True, False, True])
Out[4]: False
另请参阅:http://docs.python.org/2/library/functions.html#all