¿Cuantas veces te has topado con este patrón?
Código Python:
Ver original
def 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:
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".Ver original
def map_list(function, some_list): some_new_list = [] for i in some_list: some_new_list.append(function(i)) return some_new_list
Curiosamente esta función ya existe en python y se llama map.
Vamos a ver como trabaja.
Código Python:
Ver original
def 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.
Código Python:
Ver original
map(f3, map(f2, map(f1, l)))
Una solución sería hacer una nueva función
Código Python:
Ver original
def 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 original
def 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:
Mucho mas compacto.Ver original
l = [1, 2, 3] [i * 10 for i in l] #-> [10, 20, 30]
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 original
some_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 original
def 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:
Mucho mas simple.Ver original
l = [10, -1, 2, 4, 5] [i for i in l if i > 5]# -> [10]
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:
Tiene 2 filas y 3 columnas.Ver original
# columna # | # v [[1, 2, 3], #<- fila [4, 5, 6]]
*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:
Lo hicimos en una sola linea!!!Ver original
def create_matrix(m, n): return [[0 for j in range(n)] for i in range(m)]
¿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.