martes, 13 de mayo de 2008

Generadores en python

Python es un lenguaje multiparadigma que soporta gran cantidad de conceptos de programación, pero uno del que nunca había oido hablar y me ha llamado la atención son los generadores.

Un generador es una función especial que va creando valores sobre los que iterar.

Supongamos que queremos iterar sobre el conjunto de los números primos.

#!/usr/bin/python

from math import sqrt

def esPrimo(n):
root=int(sqrt(n));
for i in range(2,root+1):
if n%i==0:
return False;
return True;


def generadorPrimos(n):
for i in filter(esPrimo, range(2,n+1)):
yield i


for i in generadorPrimos(100):
print i;

Primero debemos definir la función esPrimo que no tiene ningún misterio, en la función generadorPrimos usamos filter, este comando produce una lista a partir de la que le pasamos como parámetro, pero tan solo con los elementos que cumplen la condición pasada en el primer parámetro.

Es decir, en el ejemplo devolvería una lista con los números primos entre 2 y n (inclusive), posteriormente iteramos sobre la lista de números primos y devolvemos cada uno de ellos. En el caso de los generadores se devuelve el valor con yield.

Ahora cada vez que queramos iterar sobre los números primos podemos usar el método generadorPrimos.

Al principio puede que cueste encontrar una utilidad práctica a los generadores, sin embargo pueden ayudar en multitud de ocasiones, unos ejemplos que se me ocurren, generar n números aleatorios entre a y b.

#!/usr/bin/python

from math import sqrt
import random

def generadorAleatorios(a,b,n):
for i in range(0,n):
yield random.randint(a, b);

for i in generadorAleatorios(1,100,10):
print i;

O incluso se pueden ir generando IPs aleatorias válidas.

#!/usr/bin/python

from math import sqrt
import random

def generadorIPs(n):
for i in range(0,n):
a=random.randint(0,255);
b=random.randint(0,255);
c=random.randint(0,255);
d=random.randint(0,255);
yield str(a)+"."+str(b)+"."+str(c)+"."+str(d);

for i in generadorIPs(10):
print i;

0 comentarios: