我对python的“all”和生成器有以下问题:
G = (a for a in [0,1])
all(list(G)) # returns False - as I expected
可是:
G = (a for a in [0,1])
all(G) # returns True!
有人可以解释一下吗?
更新: 我发誓我明白了!看看这个:
In [1]: G = (a for a in [0,1])
In [2]: all(G)
Out[2]: True
我正在使用Python 2.6.6和IPython 0.10.2,所有这些都安装在Python(x,y)包中。奇怪的是,当我使用Spider IDE时,我得到“True”(上图),而在纯控制台中得到“False”......
更新2: 正如帝斯曼指出的那样,这似乎是一个愚蠢的问题。 Python(x,y)加载numpy,所有(G)实际上调用numpy.all(G)而不是内置all()。一个快速的解决方法是写:
__builtins__.all(G)
谢谢大家的帮助!
-maciej
答案 0 :(得分:13)
啊哈!
Python(x,y)是否碰巧导入numpy? [它看起来像。]
Python 2.7.2 (v2.7.2:8527427914a2, Jun 11 2011, 15:22:34)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>>
>>> G = (a for a in [0,1])
>>> all(G)
False
>>> from numpy import all
>>>
>>> G = (a for a in [0,1])
>>> all(G)
True
>>>
以下是Robert Kern的解释:
它[all --ed]适用于数组和它可以变成数组的东西 调用C API相当于numpy.asarray()。有很多 asarray()中的魔术和特殊情况,以便解释嵌套 Python序列为数组。当我们拥有时,这种魔力相当不错 已知长度的序列;当给出一个时,它完全失败了 未知长度的任意迭代器。所以我们踢了。不幸的是,什么 然后发生的是asarray()看到一个它无法解释的对象 作为一个变成真实数组的序列,所以它产生一个rank-0数组 使用iterator对象作为值。评估为True。
答案 1 :(得分:7)
不,它没有。以下代码段返回False
G = (a for a in [0,1])
all(G) # returns False
您是否正在执行以下操作
G = (a for a in [0,1])
all(list(G)) # returns False
all(G) # returns True!
在这种情况下,当你构造列表时,你正在耗尽生成器G
,所以对all(G)
的最后调用是在一个空的生成器上,因此返回等价的all([])
- > True
。
生成器不能多次使用。
答案 2 :(得分:3)
>>> G = (a for a in [0,1])
>>> all(list(G))
False
>>> G = (a for a in [0,1])
>>> all(G)
False
否True
。但是:
>>> G = (a for a in [0,1])
>>> all(list(G))
False
>>> all(G)
True
>>> all([])
True
如果您第二次在生成器上调用all
,则会获得True
,因为生成器中没有剩余False
个项目。如您所见,任何空序列都将起作用。
对于此特定示例,all
短路,因此您返回1
后会因生成False
而生成0
(如果您不知道)不要使用list
) - 所以尽管不是空的,它会第二次返回True
。
答案 3 :(得分:0)
我在python 3.2.3中发现,如果值0在列表中,则all()将返回False。
要使all()工作,你必须避免迭代列表中的零。
这让我相信零被用作迭代的结束。
Python 3.2.3(默认,2012年4月11日,07:15:24)[MSC v.1500 32位(英特尔)]在win32上
print(all([])) # prints True
print(all([0])) # prints False
print(all([2, 3])) # prints True
print(all([2, 3, 0])) # prints False
答案 4 :(得分:0)
"""
all(iterable)
Return True if all elements of the iterable are true (or if the iterable is
empty). Equivalent to:
def all(iterable):
for element in iterable:
if not element:# if element is zero returns False
return False
return True
"""
如果你有' 0' (你的iterer中的零)你使用all时会得到False。
用零填充
l = [ x for x in range(10)]
l1 = range(10)
g = (x for x in range(10))
d = {k: v for k, v in zip(range(10), range(10)) }
t = tuple(l)
s = set(l)
for i in [ l , l1, g , d , t , s]:
print(type(i), i , "is iter " , all(i))
Out put:
<class 'list'> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] is iter False
<class 'range'> range(0, 10) is iter False
<class 'generator'> <generator object <genexpr> at 0x102a7d938> is iter False
<class 'dict'> {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9} is iter False
<class 'tuple'> (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) is iter False
<class 'set'> {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} is iter False
没有零的
l = [ x for x in range(1, 10)]
l1 = range(1, 10)
g = (x for x in range(1, 10))
d = {k: v for k, v in zip(range(1, 10), range(1, 10)) }
t = tuple(l)
s = set(l)
for i in [ l , l1, g , d , t , s]:
print(type(i), i , "is iter " , all(i))
Out put:
<class 'list'> [1, 2, 3, 4, 5, 6, 7, 8, 9] is iter True
<class 'range'> range(1, 10) is iter True
<class 'generator'> <generator object <genexpr> at 0x102a7d938> is iter True
<class 'dict'> {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9} is
iter True
<class 'tuple'> (1, 2, 3, 4, 5, 6, 7, 8, 9) is iter True
<class 'set'> {1, 2, 3, 4, 5, 6, 7, 8, 9} is iter True