Python内置“所有”与生成器

时间:2011-09-20 21:21:51

标签: python numpy

我对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

5 个答案:

答案 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