Veamos la diferencia que existe entre una función normal de Python y un generador. Vamos a verlo con un ejemplo donde pretendemos generar números pares. Primero usaremos una función normal que tiene su return. Luego usaremos un generador que no usa return sino que usa yield.
Función
#Función: imprimir los pares hasta un cierto valor
def generaPares(limite):
n=1 #contador
lista=[]
while n<=limite:
lista.append(n*2)
n+=1
return lista
pares=generaPares(10) #pares es un iterador, en este caso es una lista
#un iterador es un objeto iterable, esto es que podemos recorrer
print(pares)
for i in pares: #recorremos el objeto iterable
print(i)
Generador
El generador no usa return, en su lugar usa yield. #Generador de pares
def generaPares2(limite):
n=1
while n<=limite:
yield n*2
n+=1
pares=generaPares2(10)
for i in pares:
print(i)
Generador con next
Con next vamos pidiendo nuevos elementos del objeto iterable y el generador los va 'fabricando'. De esta forma se ahorran recursos de memoria y de tiempo de cálculo ya que los elementos se generan uno a uno a medida que next los va pidiendo. Por el contrario si usáramos una función normal, ésta ha de generar todos los elementos del la lista, lo cual supone mayor gasto de recursos. La función ha de generar todos los elementos de la lista ya que una vez finalizada la función no se pude volver a ella, salvo que se invoque nuevamente. La función una vez que finaliza pierde el contenido de todas las variables locales que usa internamente. #Generador con next
def generaPares3(limite):
n=1
while n<=limite:
yield n*2
n+=1
pares=generaPares3(10)
print(next(pares))
print("otro, por favor.")
print(next(pares))
print("otro, por favor.")
print(next(pares))
print("otro, por favor.")
print(next(pares))
print("otro, por favor.")
print(next(pares))
No hay comentarios:
Publicar un comentario