lista a traves de generador

Iniciado por PUAROT, 29 Diciembre 2016, 23:47 PM

0 Miembros y 2 Visitantes están viendo este tema.

PUAROT

Muy buenas, me estoy enterando de como funcionan los generadores y me surge una duda

si creo un generador :
Código (python) [Seleccionar]
def generador():
a,b = 0 , 1
while a < 2500:
yield a
a,b = b,a+b

este lo almaceno en una variable:
variable = generador()
y luego almaceno en una lista:
lista = list(variable)

Estarán todos los valores que genere en la lista ocupando memoria o solo se crearan a demanda por ser un generador  ?

No se si la ventaja del generador con respecto al uso de memoria sigue siendo tal al pasarlo a lista.


Once

Hola, cuando haces un list(variable) estás creando un nuevo objeto lista, en este caso a partir de los elementos de un generador.

Por lo que pierdes todas las ventajas que te brinda el generador.

Saludos!

PUAROT

Ok gracias por contestar, es lo que me imaginaba

Existe alguna forma de usar y acceder a los elementos creados con un generador como si de una lista se tratase ?

No tengo en mente ahora mismo ningún caso practico en mente, simplemente es por aprender el funcionamiento de los generadores.

Gracias otra vez !

hsk75rv


Un generador es un objeto iterable, por lo tanto, acceder a los elementos creados por el mismo
se puede con un for

Así pues:
Código (python) [Seleccionar]
def generador():
a,b = 0 , 1
while a < 2500:
  yield a
  a,b = b,a+b

variable = list(generador())
for i in variable:
    print i

Once

Cita de: PUAROT en 30 Diciembre 2016, 14:05 PM
Ok gracias por contestar, es lo que me imaginaba

Existe alguna forma de usar y acceder a los elementos creados con un generador como si de una lista se tratase ?

No tengo en mente ahora mismo ningún caso practico en mente, simplemente es por aprender el funcionamiento de los generadores.

Gracias otra vez !

La verdad lo dudo, es más, analiza un poco la estructura del generador que colocas como ejemplo en el primer comentario. Si quisieras acceder como si fuera una lista al décimo elemento, tendrías que generar TODOS los diez elemtos para poder mostrar el décimo. ahora, siquisieras mostrar el elemento 20, tendrías, que, de nuevo generar TODOS los 20 primeros elementos. Así que no tendría mucho sentido.

Creo que te estás confundiendo un poco, así que recuerda que los generadores fueron pensados para obtener una especie de lista de elementos ordenados, pero que se crean cuando se necesitan para ahorrar memoria. Son muy eficientes cuando los usas en un for porque recuerda que el for en Python no es un contador sino que recorre cualquier elemento iterable. por lo que si necesitas recorrer los primeros 2000 números en Python, necesitas iterar una lista con los 2000 números, lo que en memoria sería muy ineficiente y los generadores solucionan este problema.


Saludos!

PUAROT

Gracias por las respuestas. Estas dudas que me van surgiendo, la mayoría de las veces al leer código o al intentar escribirlo, me ayudan a entender mejor como funciona esto :-P .
La lista tiene su uso y el generador otro, si por lo que sea necesitamos acceder a los valores como una lista, tendremos que convertir el resultado del generador a lista con el consecuente uso de memoria.

Yidu

#6
Tambien puedes utilizar el generador como se utilizan las listas por comprension (En el caso de generadores se usan parantesis).

Código (python) [Seleccionar]
generador = (elem for elem in range(1, 11))

Puedes accedar a sus elementos con la funcion integrada en Python next().

Código (python) [Seleccionar]
next(generador)
next(generador)
next(generador)


SALIDA:

1
2
3


O recorrerlo integramente mediante un ciclo for:

Código (python) [Seleccionar]
for i in generador:
   print(i)


SALIDA:

1
2
3
4
5
6
7
8
9
10

Tambien se pueden hacer filtros con los datos que se van generando. Por ejemplo, solo numeros pares:

Código (python) [Seleccionar]
generador = (elem for elem in range(1, 11) if elem % 2 is 0)

SALIDA:

Código (python) [Seleccionar]
next(generador)
2
next(generador)
4
next(generador)
6
next(generador)
8
next(generador)
10
next(generador)

Traceback (most recent call last):
 Python Shell, prompt 7, line 1
builtins.StopIteration:

Si, al final te saldra la advertencia de StopIteracion. Ya que el generador se ha vaciado. Aunque esto tambien se puede hacer con un range e indicando su paso a la salida de cada elemento.

Tambien tienes la opcion con la funcion iter()

Código (python) [Seleccionar]
a = (range(1, 101))
b = iter(a)


SALIDAS:

Código (python) [Seleccionar]
next(b)
1
next(b)
2
next(b)
3


(Si no usas la el IDE interactivo deberas aplicar la funcion print() para mostrar los resultados con next().

Espero que te haya ayudado. Saludos!  :rolleyes:




PUAROT

Gracias !!!

El uso de los generadores me va quedando claro, las listas por compresion todavia no tengo claro como se crean.
Se hacer las cosa linea a linea, con su indentación,he leído algo, pero no me queda totalmente claro como se crean

hsk75rv

Cita de: PUAROT en  1 Enero 2017, 21:09 PM
Gracias !!!

El uso de los generadores me va quedando claro, las listas por compresion todavia no tengo claro como se crean.
Se hacer las cosa linea a linea, con su indentación,he leído algo, pero no me queda totalmente claro como se crean


Código (python) [Seleccionar]
lista_normal = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Lista que creamos indicando uno a uno los elementos

lista_comprension = [numeros for numeros in xrange(11)]
"""Esta lista tiene los mismos elementos que la anterior
solo que para generarla hemos hecho uso de una expresion.
Para crear listas de comprension debemos seguir la siguiente estructura:
  elemento_a_extraer iterador condicion1 condicion2 condicion3
 
Entonces en el ejemplo anterior de lista_comprension, el elemento
a extraer es numeros, variable que se genera cuando iteramos con el for,
y en este caso, no hemos puesto ninguna condicion.
El orden de ejecucion sera primero el iterador, luego las condiciones
y por ultimo la asignacion a la variable."""

lista_comprension_2 = [numeros for numeros in xrange(11) if numeros%2==0 if numeros<=4]
print lista_normal,lista_comprension,lista_comprension_2

"""La lista_comprension_2 como ves ya tiene mas condicionales, los cuales
se ejecutan de izquierda a derecha.
En este caso los elementos de la lista2 serian todos los numeros(hasta el 10)
cuyo modulo sea 0 y a la vez, menores o iguales que 4"""


Además,  ;D http://elclubdelautodidacta.es/wp/2013/04/python-listas-por-comprension-2/

PUAROT

Muy buena explicación !!    ;-) ;-) ;-)

Muchas gracias !!