Python incorporó “todo” con generadores.

Tengo el siguiente problema con “todos” y generadores de python:

G = (a for a in [0,1]) all(list(G)) # returns False - as I expected 

Pero:

 G = (a for a in [0,1]) all(G) # returns True! 

¿Alguien puede explicar eso?

ACTUALIZACIÓN: ¡Juro que entiendo esto! Mira esto:

 In [1]: G = (a for a in [0,1]) In [2]: all(G) Out[2]: True 

Estoy usando Python 2.6.6 con IPython 0.10.2, todo instalado dentro del paquete Python (x, y). Curiosamente, obtengo “Verdadero” (arriba) cuando uso el IDE de Spider, y “Falso” en la consola pura …

ACTUALIZACIÓN 2: Como señaló DSM, parece ser un problema numpy. Python (x, y) carga numpy, y all (G) en realidad estaba llamando a numpy.all (G) en lugar de a la incorporada all (). Una solución rápida es escribir:

 __builtins__.all(G) 

¡Gracias por toda tu ayuda!

-maciej

Jajaja

¿Python (x, y) pasa a importar numpy? [Parece que es así.]

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

Aquí hay una explicación de Robert Kern :

[All –ed] funciona en arreglos y cosas que puede convertir en arreglos llamando al equivalente en API de C de numpy.asarray (). Hay un montón de casos especiales y de magia en asarray () para interpretar secuencias de Python anidadas como matrices. Esa magia funciona bastante bien cuando tenemos secuencias con longitudes conocidas; falla completamente cuando se le da un iterador arbitrario de longitud desconocida. Así que apostaremos. Desafortunadamente, lo que sucede entonces es que asarray () ve un objeto que no puede interpretar como una secuencia para convertirse en una matriz real, por lo que hace una matriz de rango 0 con el objeto iterador como valor. Esto se evalúa como verdadero.

No, no lo hace. El siguiente fragmento de código devuelve Falso

 G = (a for a in [0,1]) all(G) # returns False 

¿Estás haciendo lo siguiente?

 G = (a for a in [0,1]) all(list(G)) # returns False all(G) # returns True! 

En ese caso, está agotando el generador G cuando construye la lista, por lo que la llamada final a all(G) es sobre un generador vacío y, por lo tanto, devuelve el equivalente de all([]) -> True .

Un generador no puede ser usado más de una vez.

 >>> G = (a for a in [0,1]) >>> all(list(G)) False >>> G = (a for a in [0,1]) >>> all(G) False 

No es True Sin embargo:

 >>> G = (a for a in [0,1]) >>> all(list(G)) False >>> all(G) True >>> all([]) True 

Si llama a all por segunda vez en el generador, obtendrá True , ya que no hay elementos False en el generador. Como puedes ver, cualquier secuencia vacía funcionará igual.

Para este ejemplo en particular, all los cortocircuitos, por lo que le queda 1 por generar después de que devuelve False debido al 0 inicial (si no usa la list ), por lo que devolverá True la segunda vez a pesar de no estar vacío .

Descubrí en Python 3.2.3 si el valor 0 está en la lista, todo () devolverá False.

para que todos () funcionen, debes evitar tener un cero en la lista de iteraciones.

Me lleva a creer que el cero se usa como un fin para la iteración.

Python 3.2.3 (predeterminado, 11 de abril de 2012, 07:15:24) [MSC v.1500 32 bit (Intel)] en win32

  print(all([])) # prints True print(all([0])) # prints False print(all([2, 3])) # prints True print(all([2, 3, 0])) # prints False 
 """ 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 """ 

si tiene ‘0’ (ceros en su iter) obtendrá False, cuando use todos.

iters con ceros

 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)) 

Fuera puesto

  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] is iter False  range(0, 10) is iter False   at 0x102a7d938> is iter False  {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9} is iter False  (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) is iter False  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} is iter False 

iters sin ceros

 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)) 

Fuera puesto

  [1, 2, 3, 4, 5, 6, 7, 8, 9] is iter True  range(1, 10) is iter True   at 0x102a7d938> is iter True  {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9} is iter True  (1, 2, 3, 4, 5, 6, 7, 8, 9) is iter True  {1, 2, 3, 4, 5, 6, 7, 8, 9} is iter True