2012-06-09 15 views
5

Sé que me debe estar perdiendo algo simple, pero no lo estoy viendo.Expresión del generador frente al rendimiento: ¿Por qué no funciona 'next()'?

Si tengo una expresión generadora de esta manera:

>>> serializer=(sn for sn in xrange(0,sys.maxint)) 

que puede generar, con facilidad, números enteros individuales como este:

>>> serializer.next() 
0 
>>> serializer.next() 
1 
>>> serializer.next() 
2 

Si escribo un generador de la siguiente manera:

>>> def ser(): 
... for sn in xrange(0,100000): 
...  yield sn 

No es bueno:

>>> ser().next() 
0 
>>> ser().next() 
0 
>>> ser().next() 
0 

??? Qué me estoy perdiendo ???

Respuesta

19

ser() crea el generador. Por lo tanto, cada vez que llame al ser(), le enviará una nueva instancia del generador. Es necesario usarlo al igual que la expresión:

serializer = ser() 
serializer.next() 

consideran que, si no lo hizo trabajar de esta manera, sólo se podían utilizar nunca la función ser() una vez y nunca podría restablecerla. Además, puede cambiar la función ser para aceptar un número entero máximo y hacer que su programa sea más flexible.

def ser(n=sys.maxint): 
    for sn in xrange(0, n): 
     yield sn 
+1

Thx! Sabía que tenía que ser simple ... – dawg

+2

no hay problema. definitivamente no es obvio, ya que el otro tipo importante de funciones que hacen esto (decoradores) tienen un 'envoltorio de retorno' explícito en ellos, que supongo está implícita/mágicamente creado por la declaración' yield': P –

4
ser() 

inicializa un generador nueva cada vez.

solucionarlo hacer algo como esto:

s = ser() 
next(s) # next is preferred over .next which is why .next has been removed in Py3 
next(s) 
5

En el segundo ejemplo, sigue creando una nueva instancia, comenzando con un generador nuevo.

g = ser() 
g.next() 
g.next() 

Cree el generador una vez y vuelva a utilizarlo.

Cuestiones relacionadas