148 lines
3.0 KiB
Markdown
148 lines
3.0 KiB
Markdown
# Generadores
|
|
|
|
Son funciones especiales, devuelven una secuencia de varoles, de uno, por cada llamada.
|
|
|
|
Son una forma sencilla y potente de iterador. Un iterador tiene siempre sus elementos disponibles,
|
|
un generador los va GENERANDO con un llamado al metodo **`__next()__`** .
|
|
|
|
Con esto se pueden tener generadores, que generen infitinos elementos (ej. nums. naturares).
|
|
|
|
Retornan un resultado con la sentencia "**yield**". Y la funcion queda en espera, hasta que es
|
|
invocada nuevamente.
|
|
|
|
> ***Son funciones que devuelven un objeto iterable.
|
|
> Son mas eficientes en uso de memoria, generando los items uno a la vez.***
|
|
|
|
Ejemplos:
|
|
- [Creación](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/14_generators#creaci%C3%B3n)
|
|
- [Fuera de rango \*StopIteration\*](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/14_generators#valores-fuera-de-rango)
|
|
- [Ahorro de memoria](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/14_generators#ejemplo-de-uso-para-ahorro-de-memoria)
|
|
- [Fibonacci](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/14_generators#ejemplo-secuencia-fibonacci)
|
|
|
|
----
|
|
|
|
## Creación
|
|
```python
|
|
def mi_generador():
|
|
yield 1
|
|
yield 2
|
|
yield 3
|
|
|
|
g = mi_generador()
|
|
|
|
for i in g:
|
|
print(i)
|
|
# 1
|
|
# 2
|
|
# 3
|
|
|
|
|
|
g2 = mi_generador()
|
|
|
|
print(next(g2))
|
|
# 1
|
|
|
|
print(next(g2))
|
|
# 2
|
|
```
|
|
|
|
También se pueden crear similiar al metodo de comprensión de listas,
|
|
usando **()** en vez de **[]**.
|
|
|
|
```python
|
|
mi_generador = (i for i in range(10) if i % 2 == 0)
|
|
|
|
migenerador3 = (i for i in range(1000000) if i % 2 == 0)
|
|
|
|
#for i in migenerador3:
|
|
# print(i)
|
|
#print(list(migenerador3))
|
|
# 0 2 4 6 8
|
|
|
|
milista = [i for i in range(1000000) if i % 2 == 0]
|
|
|
|
print(sys.getsizeof(milista))
|
|
# 4,1 MB
|
|
|
|
print(sys.getsizeof(migenerador3))
|
|
# 112 B
|
|
```
|
|
|
|
|
|
### Valores fuera de rango
|
|
Causan una ***excepcion StopIteration***
|
|
```python
|
|
g3 = mi_generador()
|
|
print(sum(g3))
|
|
# 6
|
|
|
|
def mi_generador2():
|
|
yield 5
|
|
yield 2
|
|
yield 4
|
|
|
|
g = mi_generador2()
|
|
print(sorted(g))
|
|
# [2, 4, 5]
|
|
|
|
|
|
def cuenta_regres(num):
|
|
print('Iniciando')
|
|
while num > 0:
|
|
yield num
|
|
num -= 1
|
|
|
|
cr = cuenta_regres(4)
|
|
print(next(cr))
|
|
print(next(cr))
|
|
```
|
|
|
|
|
|
### Ejemplo de uso, para ahorro de memoria
|
|
```python
|
|
import sys
|
|
|
|
def primer_n(n):
|
|
nums = []
|
|
num = 0
|
|
while num < n:
|
|
nums.append(num)
|
|
num += 1
|
|
return nums
|
|
|
|
# Función ocupa 8,3 MB de memoria
|
|
# print(sys.getsizeof(primer_n(1000000)))
|
|
|
|
print(primer_n(10))
|
|
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
|
|
|
|
def primer_n_gen(n):
|
|
num = 0
|
|
while num < n:
|
|
yield num
|
|
num += 1
|
|
|
|
# Función ocupa 112 KB de memoria
|
|
# print(sys.getsizeof(primer_n_gen(1000000)))
|
|
|
|
print(primer_n(10))
|
|
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
```
|
|
|
|
### Ejemplo secuencia fibonacci
|
|
```python
|
|
def fibonacci(limite):
|
|
"0, 1, 1, 2, 3, 5, 8, 13..."
|
|
a, b = 0, 1
|
|
while a < limite:
|
|
yield a
|
|
a, b = b, a + b
|
|
|
|
fibo = fibonacci(300)
|
|
for i in fibo:
|
|
print(i, end=" ")
|
|
print("")
|
|
```
|
|
|