Anuncios
Anuncios

Bienvenidos sean a este post, despues de todo lo visto anteriormente podemos pasar a ver como crear un iterador personalizado para nuestros codigos pero antes diferenciemos que es un iterador y un iterable:

  • Iterable, se considera a un objeto iterable cuando es capaz de devolver a sus miembros de una sola vez, algunos ejemplos son los list, tuple, dicts y strings, tambien son iterables objetos personalizados que definen a los metodos __iter__ o __getitem__
  • Iterador, un objeto puede ser iterador si representa un flujo de datos, para esto necesitaremos un iterador personalizado para proveer una implementacion para __iter__ que devuelve el objeto en si, y una implementacion para __next__ que devuelve el siguiente objeto del flujo de datos y se interrumpe cuando devuelve un StopIteration.

Con esto establecido vamos a ver como crear un iterador personalizado mediante un ejemplo, para ello primero crearemos una nueva clase con el siguiente codigo:

>>> class Iterador:
...     def __init__(self, datos):
...             self._datos = datos
...             self.indices = (list(range(0, len(datos), 2)) +
...                     list(range(1, len(datos), 2)))
...     def __iter__(self):
...             return self
...     def __next__(self):
...             if self.indices:
...                     return self._datos[self.indices.pop(0)]
...             raise StopIteration
... 
>>>
Anuncios
Anuncios

En esta clase como siempre usamos a __init__ para crear e iniciar una variable llamada datos, luego inicaremos una llamada indices donde sera una lista que creara una lista de valores creados por dos range, en este caso uno lo comenzaremos desde 0 y tendra el ancho de lo informado en datos e ira de a 2 pasos, el otro es exactamente lo mismo pero comenzara desde 1, es decir que el primer range solo genera numeros pares y el otro numeros impares, ya veremos para que, luego hacemos una sobrecarga a __iter__ para que se devuelve a si mismo, y una sobrecarga de __next__ donde exista un valor en indices nos devolvera la posicion de datos comenzando desde 0, si no existe mas valores en indices nos devuelve un StopIteration para detener la iteracion, vamos a ver como funcion primero creando el siguiente objeto:

>>> iterador = Iterador("EsToEsUnTeXtOdEeJeMpLo!")
Anuncios

Al objeto creado le pasaremos por medio de Iterador un texto, en este caso pasamos un texto para que salida sea mas clara, ya lo veremos, lo siguiente sera imprimirlo para ver el resultado:

>>> print(''.join(c for c in iterador))
ETEUTXOEJML!sosnetdeepo
>>>
Anuncios

Lo siguiente sera usar a join para pasar por todo el «iterador» que creamos, si observan se cumple lo que solicitamos, es decir separamos las posiciones pares e impares, para que se observe mejor separamos las mayusculas de las minusculas porque primero tenemos una lista con todas las mayusculas y luego otra con las minusculas, pero esto tambien lo podemos hacer de manera manual, veamos como se hace:

>>> iterador = Iterador("Hola")
>>> it = iter(iterador)
>>> print(next(it))
H
>>> print(next(it))
l
>>> print(next(it))
o
>>> print(next(it))
a
>>> print(next(it))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/tinchicus/lenguajes/python/iterador.py", line 13, in __next__
    raise StopIteration
StopIteration
>>>
Anuncios

Creamos un nuevo objeto iterador con un mensaje corto, con este objeto creado usaremos la funcion iter para iterar sobre este, el siguiente paso sera utilizar a next para mostrar cada uno de los valores y una vez alcanzado el final nos devuelve el final de la iteracion, con esto creamos un nuevo iterador acorde a lo que necesitamos para nuestros codigos, porque este tipo de iteracion no existe dentro de python y vemos como nos puede beneficiar este tipo de cambios donde aplicamos mucho de lo visto anteriormente.

Anuncios

En resumen, hoy hemos visto como crear un iterador personalizado, como este se hace por medio de muchos de los temas visto anteriormente, tambien hemos visto como podemos crear un iterador para una necesidad X de nuestro codigo y que este trabaje de varias formas como si fuera parte del sistema, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios

Donación

Es para mantenimento del sitio, gracias!

$1.50