Funciones map, filter, reduce y list comprehension

Funciones lambda, list, map, filter y reduce

En el artículo de ciclo for habíamos visto que podemos acceder a los elementos de una lista ( y otros objetos iterables tales como strings, tuples, diccionarios etc) utilizando ciclos for. En este artículo vamos a ver cómo aplicar una función a cada elemento de una lista, filtrar una lista por una condición o reducir una lista a un valor aplicando una función.

Función para aplicar a todos los elementos de una lista

En algunas ocasiones es necesario aplicar una función a todos los elementos de una lista, o efectuar un filtrado de los elementos de acuerdo con una condición o aplicar una expresión si se cumple o no una condición. Para realizar estas acciones existen varios métodos que pueden ser aplicados. El método más intuitivo, pero más ineficiente es utilizar un ciclo for, luego en orden de sencillez y elegancia tenemos el uso de las funciones map y filter en conjunto con la función list y las funciones lambda. Por último, el método que parece ser el más eficiente es el uso de las estructuras denominadas list comprehension.

Función con ciclo for

Quizás la forma más simple, porque ya conocemos cómo aplicar el concepto de función y de ciclo for, es utilizar una función que contenga un ciclo for, y que vaya aplicando la función elemento por elemento a lista. Esta es una forma muy intuitiva de realizar esta tarea, es bastante explícita en la forma en que se hacen las operaciones, sin embargo, no es una forma eficiente y elegante de hacer las cosas con python.

La forma de hacer que una función se aplique a cada elemento de una lista es la siguiente:

1.- Crear una función que acepte como argumento una lista.

2.- Crear una lista vacía, que va a almacenar los resultados de aplicar la función a los elementos de la lista de entrada.

3.- Crear un ciclo for que recorra la lista de entrada.

4.- Dentro del ciclo for aplicar la función a cada elemento de la lista de entrada y agregar el resultado a la nueva lista utilizando el método append.

5.- Regresar (return) la lista creada.

En el ejemplo siguiente vamos a crear una lista de 4 números y vamos a aplicar una función que devuelva una lista con los elementos elevados al cuadrado. El argumento de entrada de la función es una lista.

n=[4, 3, 2, 1]

n

[4, 3, 2, 1]

def square(lst1):

      lst2= []

     for num in lst1:

              lst2.append(num**2)

    return lst2

m=square(n)

m

[16, 9, 4, 1]

Función en conjunto con list y map

Una forma un poco más simple y elegante es crear una función que se aplique a números individuales. luego utilizar la función map, la cual indica que se aplique la función introducida dentro de map a la lista. para que se cree la lista debemos aplicar la función list al objeto de tipo map. La sintaxis es la siguiente.

lista_salida = list( map ( name_funcion, lista_entrada)

Si no utilizamos la función list no se mostrarán los elementos de la lista, solo se mostrará un objeto de tipo map. para ver los elementos de la lista hay que aplicar la función list a este objeto map.

por ejemplo:

variable_name = map ( name_funcion, lista_entrada)

lista_salida = list (variable_name)

Es como aplicar la función en dos fases, primero map, y luego list. Esto se hace solo con motivos didácticos, lo usual es utilizar la línea de código completa:

list(map(funcion, lista_de entrada)

En el siguiente ejemplo se va a crear la misma función de elevar al cuadrado, y se va a llamar sq2(). notar que esta función no se aplica a listas, sino a valores individuales.

def sq2(x):

    return x**2

función sq2 aplicada a un valor individual

sq2(5)

25

función sq2 aplicada a todos los elementos de una lista

Notar que solo se coloca el nombre de la función sq2, sin colocar paréntesis y ningún argumento. Esta es una solución simple y elegante que solo necesita una función y una línea de código para aplicar la función.

g= list(map(sq2,n))

g

[16, 9, 4, 1]

Aquí vamos a ver como aplicamos la función map, y luego la función list en dos pasos

gh=map(sq2,n)

notar que al aplicar map, obtenemos un objeto de tipo map.

gh

type(gh)

map

para devolver una lista debemos utilizar la función list

gh=list(gh)

gh

[16, 9, 4, 1]

Utilizando lambda en conjunto con map y list

podemos crear una instrucción en una sola línea que combine la función y la aplicación de map.

lambda es un comando que se utiliza para introducir una función en una sola línea y su sintaxis es:

f = lambda (lista de parámetros) : función

La asignación a un nombre de variable es opcional, y en este caso, que va combinada en una sola instrucción no se utiliza.

La sintaxis de map con lambda

nombre_lista= list(map(lambda (lista de parametros): función , lista_entrada))

Hagamos el mismo ejemplo de obtener el cuadrado de los elementos de una lista. Esta es una solución elegante en una sola línea.

lis_lambda= list(map(lambda x: x**2, n))

lis_lambda

[16, 9, 4, 1]

List Comprehension

Esta es una estructura de lo más eficiente, en una sola línea sin aplicar las funciones list y map, aplica una función a los elementos de una lista.

nombre_lista= [ expresion for elemento in iterable]

Aquí la expresión que vamos a pasar a la estructura de list comprehension es el cuadrado de un número

h= [x**2 for x in n]

h

[16, 9, 4, 1]

Uso de la función filter en conjunto con list y lambda

la función filter se utiliza en conjunción con lambda para obtener una lista filtrada al utilizar una condición.

nombre_lista= list(filter(lambda (lista de parametros): condición , lista_entrada))

La condición es una operación con alguno de los operadores de comparación.

filtrada=list(filter(lambda x: x>2,n))

filtrada

[4, 3]

List comprehension con condicional

Esta es una estructura muy eficiente que también se puede utilizar para obtener una lista filtrada por una condición, aquí continuaremos utilizando nuestra lista de 4 elementos llamada n, e igual solicitaremos los elementos que son mayores que 2.

La sintaxis es la siguiente:

Nueva_lista= [ expresion for elemento in iterable if condicion]

La condición es una expresión de comparación, por ejemplo, x>2, x<2, x==0, etc

mayor_2=[x for x in n if x>2]

# Esta es una expresión muy simple, elegante y legible.

mayor_2

[4, 3]

list comprehension para efectuar una acción sobre los elementos que no cumplen la condición.

También existe una sintaxis para efectuar una acción sobre los elementos que no cumplen la condición establecida. En el ejemplo anterior habíamos filtrado por los elementos mayores de 2, ahora vamos a colocar un 100 para los valores mayores de 2 y un 5 para los valores menores o iguales de 2.

La sintaxis es la siguiente:

Nueva_lista= [ expresion if condicion else statement for elemento in iterable]

ma2=[100 if x>2 else 5 for x in n]

print(n)

print(ma2)

[4, 3, 2, 1]

[100, 100, 5, 5]

Aquí los elementos de n que son mayores de 2 se le asigna un valor de 100 y a los menores un valor de 5.

Función reduce

Para utilizar la función reduce hay que importar el módulo functools. como su nombre lo indica reduce una lista a un solo valor. esta función fue sacada de las funciones del core de python y se enviaron al módulo functools, así que si se desea utilizar esta función hay que importar el módulo functools. Esta función por lo general se utiliza en combinación con las funciones de tipo lambda.

La sintaxis es la siguiente:

import functools

variable = functools.reduce(expresión, lista)

En el siguiente ejemplo se va a calcular la suma de los elementos de una lista utilizando la función reduce. Aquí la función reduce suma los primeros dos elementos de la lista, y el resultado se suma al siguiente elemento y así hasta llegar al último elemento. El resultado final es la suma de los 4 elementos de la lista [47, 11, 42, 13].

import functools

functools.reduce(lambda x,y: x+y, [47,11,42,13])

113

En el siguiente ejemplo vamos a crear una lista de los primeros 100 números naturales utilizando la función range() y vamos a obtener su suma utilizando la función reduce.

Suma100= functools.reduce(lambda x, y: x+y, range(1,101))

# Esta función suma los primeros 100 números naturales

Suma100

5050

En el siguiente ejemplo vamos a crear una lista de los primeros 10 números naturales utilizando la función range() y vamos a obtener su producto.

prod10=functools.reduce(lambda x, y: x*y, range(1,11))

# calcula el producto de los 10 primeros números naturales

prod10

3628800

En el siguiente ejemplo vamos a crear una lista y vamos a crear una función lambda que seleccione el mayor de 2 números. Luego con la función reduce vamos a obtener el valor máximo de la lista de números.

mis_num=[23, 67, 35, 87, 21, 9, 2, 56]

f=lambda x,y: x if (x>y) else y

mimax=functools.reduce(f,mis_num)

# aquí se creó una función lambda con nombre f

#y se introdujo como f en la función reduce

mimax

87

Deja un comentario