2009-06-07 10 views
9

Solo mirando generadores Python, realmente impresionado con ellos, pero ¿hay alguna cosa para no usarlos? Estaba pensando en la codificación C pasada donde la lectura de un archivo, o las acciones del usuario serían áreas. Por ejemplo, ¿se podría usar el generador para solicitar al usuario la entrada (entrada de datos base?) Y el proceso de la función de llamada que ingresa? ¿Hay algún problema de rendimiento o limpieza que preocuparse?Python Generator: qué no usarlo para

Respuesta

12

Uno de los problemas con los generadores es que consiguen "consumido". Esto significa que si necesita repetir la secuencia nuevamente, necesita crear el generador nuevamente.

Si la evaluación diferida es un problema, entonces probablemente no desee una expresión de generador. Por ejemplo, si desea realizar todos sus cálculos por adelantado (por ejemplo, para poder liberar un recurso), es probable que la comprensión de la lista o el ciclo sea mejor.

Si usa psyco, obtendrá un aumento de velocidad significativo para las expresiones de lista y para los bucles, pero no para los generadores.

También es obvio que si necesita obtener la longitud de su secuencia por adelantado, entonces no quiere un generador.

13

Los generadores no persisten bien.

Generalmente, se produce un error al intentar persistir un objeto del generador.

>>> def generatorForEvenKeys(aDictionary): 
    for k in aDictionary: 
     if k % 2 == 0: yield aDictionary[k] 

>>> x = generatorForEvenKeys(someDictionary) 
>>> pickle.dump(x,file('temp.dat','wb')) 

le consigue el error siguiente:

TypeError: can't pickle generator objects 
+0

+1 bueno saber – ebo

+0

¿Puede dar un ejemplo? – bayer

+0

bayer: Ejemplo de lo siguiente: Estoy iterando sobre un documento de texto y las palabras que regresan. Quiero encurtir el generador para poder seguir leyendo el documento de texto exactamente donde lo dejé. Oops! Hipocresía. Qué PITA. –

1

utiliza un generador cuando usted quiere tener algo que sea iterateable, sin mantener toda la lista en la memoria (esta es la razón por xrange admite secuencias mucho más largas que range en Python 2.x e inferior)

Cuando necesite para cargar toda la "lista de cosas para ceder" en la memoria, no tiene mucho sentido usar un generador; también puede devolver una lista.

Para un ejemplo (un poco artificial):

def my_pointless_generator(x): 
    thedata = range(x) # or thedata = list(range(x)) in Python 3.x 
    for x in thedata: 
     yield x 

..can ser reescrito tan eficientemente como sea ..

def my_pointless_generator(x): 
    return range(x)