一般而言:
all
和any
是函数,它们接受某些可迭代对象并在以下情况下返回True
:
all
的情况下,可迭代对象中没有值为falsy;
any
的情况下,至少有一个值为truthy。
当且仅当bool(x) == False
时,值x
为falsy。
当且仅当bool(x) == True
时,值x
为truthy。
可迭代对象中的任何非布尔元素都是完全可以接受的 - 根据以下规则,bool(x)
将任何x
映射或强制转换:
0
、0.0
、None
、[]
、()
、[]
、set()
和其他空集合映射到False
- 所有其他值都映射到
True
。
对于'truthy'/'falsy',bool
的文档字符串使用术语“true”/“false”,对于具体的布尔值,则使用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
。这就好像你执行了以下操作:
any(elem for elem in tmp)
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
any()
和all()
的工作原理:当“可迭代对象(iterable)”中有元素为真时,any()
返回True
,all()
返回True
;如果可迭代对象为空,则any()
和all()
都返回False
。 - Matt Ball