La comprensión de listas es una construcción en Python que nos permite crear listas a partir de otras listas, tuplas y cualquier iterable.
Nos permite escribir en forma más concisa un algoritmo. Veamos con un ejemplo como lo resolvemos con y sin comprensión de listas.
Definir una lista con 5 valores enteros, luego a partir de la primer lista generar una segunda lista con los valores elevados al cuadrado.
lista1=[8, 5, 4, 10, 2] lista2=[] for elemento in lista1: lista2.append(elemento*elemento) print("Lista 1") print(lista1) print("Nueva lista") print(lista2)
Mediante la construcción de comprensión de listas tenemos:
lista1=[8, 5, 4, 10, 2] lista2=[elemento*elemento for elemento in lista1] print("Lista 1") print(lista1) print("Nueva lista") print(lista2)
Como vemos lo resolvemos en una sola línea:
lista2=[elemento*elemento for elemento in lista1]
Lo que hacíamos en 3 líneas:
lista2=[] for elemento in lista1: lista2.append(elemento*elemento)
La sintaxis para la comprensión de listas requiere disponer un ciclo repetitivo a la derecha 'for elemento in lista1' y el valor a generar a la izquierda 'elemento*elemento':
lista2=[elemento*elemento for elemento in lista1]
Esta construcción para el recorrido de iterables se ejecuta más rápido que la forma tradicional. Requiere un poco de tiempo para adaptar nuestro razonamiento a la nueva sintaxis.
Se tiene una lista con un conjunto de tuplas con los nombres y edades de personas:
personas=[('pedro',33),('ana',3),('juan',13),('carla',45)]
Generar una lista con las personas mayores de edad.
personas=[('pedro',33),('ana',3),('juan',13),('carla',45)] personas_mayores=[per for per in personas if per[1]>=18] print(personas_mayores)
Mediante el for recuperamos cada persona en la nueva lista si su edad es mayor o igual a 18:
personas_mayores=[per for per in personas if per[1]>=18]
Generar una lista con todos los valores múltiplos de 8 comprendidos entre 1 y 500.
multiplos8=[valor for valor in range(1,501) if valor%8==0] print(multiplos8)
Disponemos un for que recorre los valores del 1 al 500 inclusive, cada vez que el resto de dividir dicho valor por 8 se verifica verdadero procedemos a guardar dicho valor en la lista 'multiplos8'.
Podemos utilizar más de un for cuando empleamos la característica de 'List Comprehensions' de Python.
Se tiene una lista de nombres de personas. Generar otra lista cuyos elementos sean a su vez listas con dos nombres cada uno.
Tener en cuenta que nunca se debe combinar el mismo nombre dos veces.
nombres=['juan','pablo','luis','mauro','hector'] nombres_compuestos=[[nombre1,nombre2] for nombre1 in nombres for nombre2 in nombres if nombre1!=nombre2] print(nombres_compuestos)
Podemos comprobar que conciso ha quedado el algoritmo para generar pares de nombres:
Si analizamos:
nombres_compuestos=[[nombre1,nombre2] for nombre1 in nombres for nombre2 in nombres if nombre1!=nombre2]
Cada vez que la condición del if se verifica verdadera: 'if nombre1!=nombre2' se genera una lista con los dos nombres: '[nombre1,nombre2]'.
Como tenemos dos estructuras for cada vez que de ejecuta el for interno completamente avanza uno el for externo: 'for nombre1 in nombres for nombre2 in nombres'.
El mismo algoritmo pero sin utilizar 'List Comprehensions' es:
nombres=['juan','pablo','luis','mauro','hector'] nombres_compuestos=[] for nombre1 in nombres: for nombre2 in nombres: if nombre1!=nombre2: nombres_compuestos.append([nombre1,nombre2]) print(nombres_compuestos)
Requiere tiempo para habituarse a las 'List Comprehensions', pero una vez que le tomamos la mano podemos obtener grandes ventajas en la definición de algoritmos muy breves.
Vamos a resolver un problema clásico que a muchos programadores le han hecho en su primer entrevista para un puesto de programador.
Codificar un programa que muestre en pantalla los números del 1 al 100, sustituyendo los múltiplos de 3 por el palabra "Fizz" y, a su vez, los múltiplos de 5 por "Buzz". Para los números que, al tiempo, son múltiplos de 3 y 5, mostrar el mensaje "FizzBuzz".
for nro in range(1,101): if nro%3==0 and nro%5==0: print("FizzBuzz") elif nro%3==0: print("Fizz") elif nro%5==0: print("Buzz") else: print(nro)
Ahora la solución de este problema empleando 'List Comprehensions'.
print(["Fizz"*(not nro%3) + "Buzz"*(not nro%5) or nro for nro in range(1, 101)])
Con una única línea tenemos tenemos una lista con la secuencia que pide el problema: