2010-08-03 20 views
49

Me gustaría saber qué sucede cuando paso el resultado de una función de generador a enumerar de python(). Ejemplo:enumerar() - ing un generador en Python

def veryBigHello(): 
    i = 0 
    while i < 10000000: 
     i += 1 
     yield "hello" 

numbered = enumerate(veryBigHello()) 
for i, word in numbered: 
    print i, word 

¿La enumeración se repite perezosamente, o arrastra todo al primero? Estoy 99.999% seguro de que es flojo, entonces ¿puedo tratarlo exactamente igual que la función del generador, o tengo que estar pendiente de algo?

+0

supongo que quiere decir que se incrementa i en veryBigHello. – robert

+0

@robert: si no estoy confundiendo, aumente automáticamente –

+0

@the_drow No en la función 'veryBigHello'. –

Respuesta

61

Es flojo. Es bastante fácil demostrar que es el caso:

>>> def abc(): 
...  letters = ['a','b','c'] 
...  for letter in letters: 
...   print letter 
...   yield letter 
... 
>>> numbered = enumerate(abc()) 
>>> for i, word in numbered: 
...  print i, word 
... 
a 
0 a 
b 
1 b 
c 
2 c 
+0

¿Es este Python 2 o 3 (o ambos)? ¿Es perezoso en ambos? Probé en Python 2 y * es * flojo. – becko

10

Ya que se puede llamar a esta función sin salir de excepciones de memoria que definitivamente es perezosa

def veryBigHello(): 
    i = 0 
    while i < 1000000000000000000000000000: 
     yield "hello" 

numbered = enumerate(veryBigHello()) 
for i, word in numbered: 
    print i, word 
27

Es incluso más fácil de decir que cualquiera de los anteriores sugieren :

$ python 
Python 2.5.5 (r255:77872, Mar 15 2010, 00:43:13) 
[GCC 4.3.4 20090804 (release) 1] on cygwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> abc = (letter for letter in 'abc') 
>>> abc 
<generator object at 0x7ff29d8c> 
>>> numbered = enumerate(abc) 
>>> numbered 
<enumerate object at 0x7ff29e2c> 

Si enumeración no llevó a cabo la evaluación perezosa volvería [(0,'a'), (1,'b'), (2,'c')] o algún equivalente (casi).

Por supuesto, enumerar es realmente sólo un generador de lujo:

def myenumerate(iterable): 
    count = 0 
    for _ in iterable: 
     yield (count, _) 
     count += 1 

for i, val in myenumerate((letter for letter in 'abc')): 
    print i, val 
+2

Gracias por esta explicación. Me costó un poco descifrar la respuesta aceptada. Al menos hasta que yo vea el tuyo – trendsetter37

+1

Esta debería ser la respuesta aceptada – cowbert

Cuestiones relacionadas