Vamos empezar comprensión de listas sin comprensión de listas.
¿Cuantas veces te has topado con este patrón?
Código Python:
Ver originaldef some_function(x):
return x * 10
some_list = [1, 2, 3]
some_new_list = []
for i in some_list:
x = some_function(i)
some_new_list.append(x)
Básicamente lo que hacemos es, tenemos una lista y queremos que cada elemento pase por una función, en este caso nuestra función
some_function solo multiplica por 10 un elemento dado
x.
Como sabemos en python todo es un objeto y las funciones no son una excepción.
Así que podemos pasar una función como parámetro.
Código Python:
Ver originaldef map_list(function, some_list):
some_new_list = []
for i in some_list:
some_new_list.append(function(i))
return some_new_list
Genial ahora hicimos una función que le pasamos una función y una lista como parámetro y nos regresa una lista nueva con cada elemento "procesado".
Curiosamente esta función ya existe en python y se llama
map.
Vamos a ver como trabaja.
Código Python:
Ver originaldef f(x):
return x * 10
l = [1, 2, 3]
map(f, l)
#map regresa [10, 20, 30]
Esto es genial excepto por un pequeño detalle.
Si quiero procesar cada elemento en una lista con muchas funciones esto se vuelve feo. Sin mencionar el uso de memoria.
Una solución sería hacer una nueva función
Código Python:
Ver originaldef f4(x):
return f3(f2(f1(x)))
map(f4, l)
Desafortunadamente en las versiones de python 3.x map, filter y reduce no están incluidas.
Entonces el código que escriba usando map, filter o reduce no puede ser ejecutado en python 3.x
Sin embargo puedes usar compresión de listas.
Entonces en vez de tener
Código Python:
Ver originaldef f(x):
return x * 10
l = [1, 2, 3]
[f(i) for i in l] #-> [10, 20, 30]
El truco de esto es leerlo tal como lo harías en español o ingles
f(i) para i en l, entonces esto te genera una lista "procesada" (esto es que cada elemento fue procesado por una función. Ademas puedes ahorrarte la función y escribirlo directamente en la comprensión de listas.
Código Python:
Ver originall = [1, 2, 3]
[i * 10 for i in l] #-> [10, 20, 30]
Mucho mas compacto.
Ahora que pasa si deseo seleccionar ciertos elementos que cumplan con algún criterio. Y vamos a empezar con el código sencillo.
Código Python:
Ver originalsome_list = [10, -1, 2, 4, 5]
some_new_list = []
for i in some_list:
if i > 5:
some_new_list.append(i)
Lo único que hacemos es seleccionar o filtrar aquellos elementos que cumplan con un criterio, en este caso que sean mayor a 5.
Podemos hacer esto con
filter, que recibe una función y una lista y regresa una lista filtrada por la función.
Código Python:
Ver originaldef f(x):
return x > 5
l = [10, -1, 2, 4, 5]
filter(f, l) #[10]
Y lo mejor de todo es que también lo podemos hacer con compresión de listas.
Código Python:
Ver originall = [10, -1, 2, 4, 5]
[i for i in l if i > 5]# -> [10]
Mucho mas simple.
Ahora vamos a generar una matriz con compresión de listas.
En otros lenguajes una matriz es una tabla de elementos, las tablas tienen filas y columnas, así que accedemos a los elementos por medio de una fila y una columna, en ese orden.
En python esto sería una matriz* de 2x3.
Código Python:
Ver original# columna
# |
# v
[[1, 2, 3], #<- fila
[4, 5, 6]]
Tiene 2 filas y 3 columnas.
*Formalmente no es una matriz
Entonces vamos a generar una matriz inicialmente con ceros de tamaño m x n donde m es el numero de filas y n el numero de columnas.
Código Python:
Ver originaldef create_matrix(m, n):
return [[0 for j in range(n)] for i in range(m)]
Lo hicimos en una sola linea!!!
¿Como es esto posible?
Una de las ventajas de la compresión de listas es que las puedes anidar y puedes generar listas de listas.
Pero vamos a ver el código paso a paso
[0 for j in range(n)]
Esto genera una lista con
n ceros. Y simplemente lo que hace es generar una fila.
[... for i in range(m)]
Esto genera
... m veces.
Si los juntamos
[[0 for j in range(n)] for i in range(m)]
Entonces generamos
m filas, y cada fila tiene
n columnas.
Hasta aquí espero haberte ayudado a comprender un poco mejor compresión de listas.