Ir al contenido principal

Uso de "generadores" en Python.

Hola, mi nombre es Antonio Alfonso Martínez y en la presente ocasión me dispongo a dar unas breves pinceladas acerca del uso de los generadores en el lenguaje de programación Python.

Para empezar, diremos que los generadores constituyen un determinado tipo de estructura que, a diferencia de lo que sucede con las funciones corrientes, no nos va a devolver un valor concreto, sino un objeto iterable cuyos resultados se ven a ir generando uno a uno.

Para entender mejor la diferencia con las funciones que empleamos habitualmente vamos a crear un sencillo programa que va a generar la lista de números pares que hay entre 0 y el número que indiquemos:

generador1

Como se ve, hemos creado una función (de nombre "pares") que tomando como argumento el numero de pares que queremos hallar (variable "maximo") irá calculando los números pares (multiplicando por 2 la variable "num") e irá añadiendo el resultado a una lista (de nombre "lista_pares") que es la que finalmente devolverá de modo integro, mediante la correspondiente sentencia "return".

Hasta aquí todo correcto, no obstante, supongamos que en un primer momento, nuestro programa solo necesita hacer uso del primer valor generado (0 en el ejemplo). En este caso, estaríamos ante un supuesto de ineficiencia en el funcionamiento de nuestro programa ya que la función habría generado una lista de 10 elementos (con el correspondiente uso de memoria) de la que solo haríamos uso de uno  de ellos. Tal vez en este ejemplo concreto no suponga mucho, pero imaginemos que estuviéramos manejando grandes cantidades de información. Es en este supuesto donde el empleo de generadores puede suponer el lograr una mayor eficiencia en el consumo de memoria y tiempo de ejecución:

generador-e1533127060603.png

Para ilustrar la diferencia del generador con las funciones al uso, hemos creado un generador a partir de la función anterior ("pares") en donde podemos apreciar como primera diferencia el hecho de que en este caso, vamos a prescindir de la lista "lista_pares" debido a que, como dijimos anteriormente, lo que vamos a generar aquí no es la lista integra con todos los elementos sino un objeto iterable que nos va a devolver el primero de dichos valores mediante la instrucción "yield" (a diferencia de lo que sucede con las funciones corrientes que como sabemos usan la instrucción "return" para devolvernos el valor).
Así, si ahora pasamos a visualizar el resultado de nuestra función, mediante una variable a la que hemos llamado "num_pares":

con solo ob

Vemos como la función nos ha devuelto el objeto iterable al que nos hemos referido con anterioridad. No obstante, cuando usemos este tipo de estructuras en un programa, lo normal, es que lo que deseemos obtener sean los valores generador con la instrucción "yield". Para poder ir visualizando tales resultados (que en nuestro ejemplo se corresponde con los 10 primeros números pares), haremos uso de la instrucción "next" del modo siguiente ("print(next(num_pares))"):

itera0

Como se ve en la imagen, al imprimir (haciendo uso del método "next") el valor de "num_pares", hemos obtenido tan solo el primero de los valores (el 0) de la lista de números pares, quedando en suspenso la generación de los restantes 9 valores, los cuales nos irán siendo devueltos uno a uno cada vez que volvamos a llamar a la función con el método "next", tal y como se aprecia en la imagen:

itera2

De este modo, nuestro hipotético programa podría ir accediendo, sucesivamente a cada uno de los elementos generados por la función, sin necesidad, en cada vez, de reservar espacio de memoria para los elementos que no van a ser usados en ese mometo concreto (reservándose espacio solo para el elemento concreto que vaya a necesitar el programa).

Visto el proceso, cabe formularse el supuesto en el que una vez que nuestro programa ha hecho uso de la totalidad de los elementos devueltos por el generador (que en nuestro ejemplo hemos ido visualizando con "print"), pretendemos reiniciar todo el proceso. En este punto, alguno podría pensar que se puede hacer haciendo, nuevamente, uso de la instrucción. No obstante si llevamos a cabo tal acción, obtendremos lo siguiente:

itera

Como se puede ver, en ese caso se nos genera un error con el mensaje "StopIteration". Esto, lo que nos está indicando es que el proceso de generación, sucesiva de valores, en principio, solo se puede llevar a cabo una sola vez. Esto ha de ser tenido en cuenta en la medida de que, para volver a iniciar el proceso tendríamos, básicamente, 2 opciones: La primera de ellas sería, naturalmente, la de volver a definir la función con su generador. La otra, podría ser la de haber ido añadiendo cada uno de los valores generados a una lista, de forma sucesiva.

La elección entre uno de tales métodos deberá hacerse en función de las características de nuestro programa y de la cantidad de datos que estemos manejando: Así, para el caso en el que estemos ante una gran cantidad de datos, parece que el primer método (volver a definir la función) puede ser el más adecuado. Por contra si nuestros datos han sido generados por una función más compleja (y por tanto que necesite un mayor tiempo e ejecución) Parece que el segundo método (guardado de datos en lista) parece el más efectivo ya que evitará el tener que hacer uso de la función nuevamente.

En futuros artículos, seguiremos dando detalles acerca de las posibilidades y utilidades que pueden ofrecernos los generadores.

Saludos.









Comentarios

Entradas más populares de este blog

Descargar vídeos y audios de YouTube con Python y Pafy

Introducción: YouTube es una plataforma que nos permite disfrutar de vídeos informativos, películas, música y mucho, mucho más. Siempre que escuchamos una canción queremos descargarla, si vemos un vídeo también queremos descargarlo, de esta manera podríamos verlos desde donde queramos sin necesidad de una conexión a Internet. Hoy te enseñare a descargar vídeos y audios de el sitio web conocido como YoutTube, esto lo lograremos haciendo uso de una librería llamada Pafy, si aun no tienes la librería Pafy, puedes descargarla ingresando al siguiente enlace:  Librería Pafy . Usando Pafy: Pafy una biblioteca de Python para descargar contenido de YouTube y recuperar metadatos. Antes de descargar contenido, usaremos a Pafy para obtener información de un vídeo especifico. A continuación te mostrare un ejemplo para obtener el titulo de un vídeo. import pafy url_video = " https://www.youtube.com/watch?v=JkK8g6FMEXE " video = pafy.new(url_video) pr

Calculando el factorial de un número (ejemplo de función recursiva).

Hola, mi nombre es Antonio Alfonso Martínez y en el presente artículo me dispongo a explicar un sencillo método para calcular el factorial de un número haciendo uso del concepto de recursividad. Para empezar, diremos que el factorial de un número natural "n" es el resultado del producto de todos los números desde 1 hasta dicho número "n". Así, para efectuar el calculo del factorial de un número, vamos a emplear una sencilla función a la que daremos el nombre de "factorial". De modo, que, partiendo del hecho de que el factorial de 1 y 0 es 1, construiremos nuestra función (a la que daremos el nombre de "factorial") para realizar el calculo del factorial de 5: Lo que hace esta función, es tomar como argumento un número "n". de modo que si este es 0 o 1 ("if n==0 or n==1:") la función devolverá directamente como resultado el número 1 ("resultado=1"). Sin embargo si dicho número "n" es mayor que

Sistema Hexadecimal - Sistema de numeración posicional

Sistema Hexadecimal El sistema hexadecimal es un sistema numérico que tiene como base el numero 16, y es una variante de los numero binarios El sistema hexadecimal es utilizado por nuestros ordenadores con el fin de abreviar valores de datos e instrucciones de memoria. Esta es una imagen que muestra el contenido de un archivo con exención 'dll' en un editor de texto, como el editor de texto no reconoce este tipo de archivo, nos lo muestra de esta manera: Como se puede apreciar, en vez de ver una gran cantidad de 0 y 1, vemos que hay grupos de 4 dígitos, y si observamos, vemos que son grupos de dígitos hexadecimales. El archivo cuentan con más de 48 mil lineas, por ello no se me es posible mostrarlo todo. Este es uno de los usos del sistema hexadecimal para abreviar grandes cantidades de 0 y 1. Ustedes mismos pueden hacer la prueba con una imagen o con cualquier otro tipo de texto. El sistema hexadecima, esta conformado por solo 16 dígitos. A continuación te los