¿Cómo funciona exactamente la comprensión de un generador?

¿Qué hace la comprensión del generador? ¿Como funciona? No pude encontrar un tutorial al respecto.

¿Entiendes la lista de comprensión? Si es así, una expresión generadora es como una lista de comprensión, pero en lugar de encontrar todos los elementos que le interesan y agruparlos en una lista, espera y produce cada elemento fuera de la expresión, uno por uno.

Versión de python2:

>>> my_list = [1, 3, 5, 9, 2, 6] >>> filtered_list = [item for item in my_list if item > 3] >>> print filtered_list [5, 9, 6] >>> len(filtered_list) 3 >>> # compare to generator expression ... >>> filtered_gen = (item for item in my_list if item > 3) >>> print filtered_gen # notice it's a generator object  >>> len(filtered_gen) # So technically, it has no length Traceback (most recent call last): File "", line 1, in  TypeError: object of type 'generator' has no len() >>> # We extract each item out individually. We'll do it manually first. ... >>> filtered_gen.next() 5 >>> filtered_gen.next() 9 >>> filtered_gen.next() 6 >>> filtered_gen.next() # Should be all out of items and give an error Traceback (most recent call last): File "", line 1, in  StopIteration >>> # Yup, the generator is spent. No values for you! ... >>> # Let's prove it gives the same results as our list comprehension ... >>> filtered_gen = (item for item in my_list if item > 3) >>> gen_to_list = list(filtered_gen) >>> print gen_to_list [5, 9, 6] >>> filtered_list == gen_to_list True >>> 

Versión de python3:

cambiar next() a __next__()

Debido a que una expresión generadora solo tiene que producir un elemento a la vez, puede generar grandes ahorros en el uso de la memoria. Las expresiones generadoras tienen más sentido en los escenarios en los que necesita tomar un elemento a la vez, hacer muchos cálculos basados ​​en ese elemento y luego pasar al siguiente elemento. Si necesita más de un valor, también puede usar una expresión de generador y capturar algunos a la vez. Si necesita todos los valores antes de continuar con su progtwig, use una lista de comprensión en su lugar.

Una comprensión generadora es la versión perezosa de una lista de comprensión.

Es como una lista de comprensión, excepto que devuelve un iterador en lugar de la lista, es decir, un objeto con un método next () que producirá el siguiente elemento.

Si no está familiarizado con las listas de comprensión, consulte aquí y para los generadores, consulte aquí .

La comprensión de lista / generador es una construcción que puede utilizar para crear una nueva lista / generador a partir de uno existente.

Digamos que quieres generar la lista de cuadrados de cada número del 1 al 10. Puedes hacer esto en Python:

 >>> [x**2 for x in range(1,11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 

aquí, el range(1,11) genera la lista [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] , pero la función de range no es un generador antes de Python 3.0, y por lo tanto el constructo I He utilizado es una lista de comprensión.

Si quisiera crear un generador que haga lo mismo, podría hacerlo así:

 >>> (x**2 for x in xrange(1,11))  

Sin embargo, en Python 3, el range es un generador, por lo que el resultado depende solo de la syntax que use (corchetes o corchetes).

La comprensión del generador es una forma fácil de crear generadores con una estructura determinada. Digamos que desea un generator que genere uno por uno todos los números pares en su your_list . Si lo creas utilizando el estilo de la función sería así:

 def allEvens( L ): for number in L: if number % 2 is 0: yield number evens = allEvens( yourList ) 

Podrías lograr el mismo resultado con esta expresión de comprensión del generador:

 evens = ( number for number in your_list if number % 2 == 0 ) 

En ambos casos, cuando llama a la next(evens) , obtiene el siguiente número par en your_list .

La comprensión del generador es un enfoque para crear iterables, algo así como un cursor que se mueve en un recurso. Si conoce el cursor mysql o el cursor mongodb, es posible que tenga en cuenta que los datos reales completos nunca se cargan en la memoria de una vez, sino de uno en uno. El cursor se mueve hacia adelante y hacia atrás, pero siempre hay un elemento de una fila / lista en la memoria.

En resumen, al utilizar la comprensión de los generadores, puede crear cursores fácilmente en python.

Otro ejemplo de comprensión del generador:

 print 'Generator comprehensions' def sq_num(n): for num in (x**2 for x in range(n)): yield num for x in sq_num(10): print x