Python встроенный "все" с генераторами - PullRequest
5 голосов
/ 21 сентября 2011

У меня следующая проблема с 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!

Кто-нибудь может это объяснить?

UPDATE: Клянусь, я понял это! Проверьте это:

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). Как ни странно, я получаю «True» (выше), когда я использую Spider IDE, и «False» в чистой консоли ...

ОБНОВЛЕНИЕ 2: Как указал DSM, это, похоже, проблема с проблемами. Python (x, y) загружает numpy, и все (G) фактически вызывали numpy.all (G), а не встроенную функцию all (). Быстрый обходной путь - написать:

__builtins__.all(G)

Спасибо всем за помощь!

-maciej

Ответы [ 5 ]

13 голосов
/ 21 сентября 2011

Ага!

Может ли 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
>>> 

Вот объяснение Роберт Керн :

Это [все --ed] работает с массивами и вещамион может превратиться в массивы, вызвав эквивалент Cump API numpy.asarray ().В asarray () есть тонна магии и особых случаев, чтобы интерпретировать вложенные последовательности Python как массивы.Эта магия работает довольно хорошо, когда у нас есть последовательности с известной длиной;он полностью терпит неудачу, когда ему дается произвольный итератор неизвестной длины.Итак, мы понты.К сожалению, тогда происходит то, что asarray () видит объект, который он не может интерпретировать как последовательность, превращающуюся в реальный массив, поэтому он создает массив ранга 0 с объектом итератора в качестве значения.Это оценивает к Истине.

7 голосов
/ 21 сентября 2011

Нет, это не так.Следующий фрагмент возвращает 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.

Генератор не может использоваться более одного раза.

3 голосов
/ 21 сентября 2011
>>> 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 во второй раз, несмотря на то, что он не пустой.

0 голосов
/ 09 июля 2017
"""
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» (нули в вашем иттерре), вы получите 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 out:

<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 out:

<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
0 голосов
/ 21 февраля 2013

Я обнаружил в python 3.2.3, если значение 0 находится в списке, all () вернет False.

, чтобы все () работали, чтобы избежать нуля в списке итераций.

Это наводит меня на мысль, что в качестве конца для итерации используется ноль.

Python 3.2.3 (по умолчанию, 11 апреля 2012 г., 07:15:24) [MSC v.150032 бит (Intel)] на win32

 print(all([]))          # prints True
 print(all([0]))         # prints False

 print(all([2, 3]))      # prints True
 print(all([2, 3, 0]))   # prints False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...