Introducción
Esta sección presenta algunos temas adicionales relacionados con los generadores, incluyendo expresiones generadoras y el módulo itertools.
This tutorial is from open-source community. Access the source code
Esta sección presenta algunos temas adicionales relacionados con los generadores, incluyendo expresiones generadoras y el módulo itertools.
Una versión generadora de una comprensión de lista.
>>> a = [1,2,3,4]
>>> b = (2*x for x in a)
>>> b
<generator object at 0x58760>
>>> for i in b:
... print(i, end=' ')
...
2 4 6 8
>>>
Diferencias con las Comprensiones de Lista.
Sintaxis general.
(<expression> for i in s if <conditional>)
También puede servir como argumento de función.
sum(x*x for x in a)
Se puede aplicar a cualquier iterable.
>>> a = [1,2,3,4]
>>> b = (x*x for x in a)
>>> c = (-x for x in b)
>>> for i in c:
... print(i, end=' ')
...
-1 -4 -9 -16
>>>
El principal uso de las expresiones generadoras es en código que realiza algún cálculo sobre una secuencia, pero solo utiliza el resultado una vez. Por ejemplo, eliminar todos los comentarios de un archivo.
f = open('somefile.txt')
lines = (line for line in f if not line.startswith('#'))
for line in lines:
...
f.close()
Con los generadores, el código se ejecuta más rápido y utiliza poco memoria. Es como un filtro aplicado a un flujo.
itertoolsEl itertools es un módulo de la biblioteca con varias funciones diseñadas para ayudar con iteradores/generadores.
itertools.chain(s1,s2)
itertools.count(n)
itertools.cycle(s)
itertools.dropwhile(predicate, s)
itertools.groupby(s)
itertools.ifilter(predicate, s)
itertools.imap(function, s1,... sN)
itertools.repeat(s, n)
itertools.tee(s, ncopies)
itertools.izip(s1,..., sN)
Todas las funciones procesan los datos de forma iterativa. Implementan varios tipos de patrones de iteración.
Más información en el tutorial Generator Tricks for Systems Programmers de PyCon '08.
En los ejercicios anteriores, escribió un código que seguía las líneas que se escribían en un archivo de registro y las analizaba en una secuencia de filas. Este ejercicio continúa construyendo sobre eso. Asegúrese de que stocksim.py siga en ejecución.
Las expresiones generadoras son una versión generadora de una comprensión de lista. Por ejemplo:
>>> nums = [1, 2, 3, 4, 5]
>>> squares = (x*x for x in nums)
>>> squares
<generator object <genexpr> at 0x109207e60>
>>> for n in squares:
... print(n)
...
1
4
9
16
25
A diferencia de una comprensión de lista, una expresión generadora solo se puede usar una vez. Por lo tanto, si intenta otro bucle for, no obtiene nada:
>>> for n in squares:
... print(n)
...
>>>
A veces, las expresiones generadoras se colocan en los argumentos de funciones. Al principio puede parecer un poco extraño, pero intente este experimento:
>>> nums = [1,2,3,4,5]
>>> sum([x*x for x in nums]) ## Una comprensión de lista
55
>>> sum(x*x for x in nums) ## Una expresión generadora
55
>>>
En el ejemplo anterior, la segunda versión que utiliza generadores utilizaría significativamente menos memoria si se estuviera manipulando una lista grande.
En su archivo portfolio.py, realizó algunos cálculos que implicaban comprensiones de lista. Intente reemplazarlas con expresiones generadoras.
Las expresiones generadoras a menudo son un reemplazo útil de pequeñas funciones generadoras. Por ejemplo, en lugar de escribir una función como esta:
def filter_symbols(rows, names):
for row in rows:
if row['name'] in names:
yield row
Podría escribir algo como esto:
rows = (row for row in rows if row['name'] in names)
Modifique el programa ticker.py para usar expresiones generadoras en la medida de lo posible.
¡Felicitaciones! Has completado el laboratorio de Generadores Avanzados. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.