map (), filter () y reduce () en Python con ejemplos

    Introducci贸n

    los map(), filter() y reduce() Las funciones aportan un poco de programaci贸n funcional a Python. Las tres son funciones de conveniencia que se pueden reemplazar con listas comprensivas o bucles, pero brindan un enfoque m谩s elegante y abreviado para algunos problemas.

    Antes de continuar, repasaremos algunas cosas con las que deber铆a estar familiarizado antes de leer sobre los m茅todos mencionados anteriormente:

    驴Qu茅 es una funci贸n / m茅todo an贸nimo o lambda?

    Un m茅todo an贸nimo es un m茅todo sin nombre, es decir, no vinculado a un identificador como cuando definimos un m茅todo usando def method:.

    Nota: Aunque la mayor铆a de la gente usa los t茅rminos “funci贸n an贸nima” y “funci贸n lambda” indistintamente, no son lo mismo. Este error ocurre porque en la mayor铆a de los lenguajes de programaci贸n las lambdas son an贸nimas y todas las funciones an贸nimas son lambdas. Este tambi茅n es el caso de Python. Por lo tanto, no profundizaremos en esta distinci贸n en este art铆culo.

    驴Cu谩l es la sintaxis de una funci贸n lambda (u operador lambda)?

    lambda arguments: expression
    

    Piense en lambdas como m茅todos de una l铆nea sin nombre. Funcionan pr谩cticamente igual que cualquier otro m茅todo en Python, por ejemplo:

    def add(x,y):
    	return x + y
    

    Puede traducirse a:

    lambda x, y: x + y
    

    Las lambdas difieren de los m茅todos normales de Python porque solo pueden tener una expresi贸n, no pueden contener declaraciones y su tipo de retorno es un function objeto. Entonces, la l铆nea de c贸digo anterior no devuelve exactamente el valor x + y pero la funci贸n que calcula x + y.

    驴Por qu茅 las lambdas son relevantes para map(), filter() y reduce()?

    Los tres de estos m茅todos esperan una function objeto como primer argumento. Esta function El objeto puede ser un m茅todo predefinido con un nombre (como def add(x,y)).

    Aunque, la mayor铆a de las veces, las funciones pasan a map(), filter()y reduce() son los que usar铆a solo una vez, por lo que a menudo no tiene sentido definir una funci贸n referenciable.

    Para evitar definir una nueva funci贸n para sus diferentes map()/filter()/reduce() necesidades: una soluci贸n m谩s elegante ser铆a utilizar una funci贸n breve, desechable y an贸nima que solo usar谩 una vez y nunca m谩s: una lambda.

    La funci贸n map ()

    los map() La funci贸n itera a trav茅s de todos los elementos en el iterable dado y ejecuta el function pasamos como argumento en cada uno de ellos.

    La sintaxis es:

    map(function, iterable(s))
    

    Podemos pasar tantos objetos iterables como queramos despu茅s de pasar el function queremos usar:

    # Without using lambdas
    def starts_with_A(s):
        return s[0] == "A"
    
    fruit = ["Apple", "Banana", "Pear", "Apricot", "Orange"]
    map_object = map(starts_with_A, fruit)
    
    print(list(map_object))
    

    Este c贸digo resultar谩 en:

    [True, False, False, True, False]
    

    Como podemos ver, terminamos con una nueva lista donde la funci贸n starts_with_A() fue evaluado para cada uno de los elementos de la lista fruit. Los resultados de esta funci贸n se agregaron a la lista de forma secuencial.

    Una forma m谩s bonita de hacer exactamente lo mismo es usando lambdas:

    fruit = ["Apple", "Banana", "Pear", "Apricot", "Orange"]
    map_object = map(lambda s: s[0] == "A", fruit)
    
    print(list(map_object))
    

    Obtenemos el mismo resultado:

    [True, False, False, True, False]
    

    Nota: Puede que hayas notado que hemos emitido map_object a una lista para imprimir el valor de cada elemento. Hicimos esto porque llamamos print() en una lista imprimir谩 los valores reales de los elementos. Vocaci贸n print() en map_object imprimir铆a las direcciones de memoria de los valores en su lugar.

    los map() funci贸n devuelve el map_object type, que es iterable y podr铆amos haber impreso los resultados de esta manera tambi茅n:

    for value in map_object:
        print(value)
    

    Si quieres el map() funci贸n para devolver una lista en su lugar, puede simplemente convertirla al llamar a la funci贸n:

    result_list = list(map(lambda s: s[0] == "A", fruit))
    

    La funci贸n filter ()

    Similar a map(), filter() toma una function objeto y un iterable y crea una nueva lista.

    Como el nombre sugiere, filter() forma una nueva lista que contiene solo elementos que satisfacen una determinada condici贸n, es decir, la function pasamos devoluciones True.

    La sintaxis es:

    filter(function, iterable(s))
    

    Usando el ejemplo anterior, podemos ver que la nueva lista solo contendr谩 elementos para los cuales el starts_with_A() devuelve la funci贸n True:

    # Without using lambdas
    def starts_with_A(s):
        return s[0] == "A"
    
    fruit = ["Apple", "Banana", "Pear", "Apricot", "Orange"]
    filter_object = filter(starts_with_A, fruit)
    
    print(list(filter_object))
    

    Ejecutar este c贸digo resultar谩 en una lista m谩s corta:

    ['Apple', 'Apricot']
    

    O reescrito usando una lambda:

    fruit = ["Apple", "Banana", "Pear", "Apricot", "Orange"]
    filter_object = filter(lambda s: s[0] == "A", fruit)
    
    print(list(filter_object))
    

    La impresi贸n nos da el mismo resultado:

    ['Apple', 'Apricot']
    

    La funci贸n reduce ()

    reduce() funciona de manera diferente a map() y filter(). No devuelve una nueva lista basada en el function e iterable hemos pasado. En cambio, devuelve un solo valor.

    Adem谩s, en Python 3 reduce() ya no es una funci贸n incorporada, y se puede encontrar en el functools m贸dulo.

    La sintaxis es:

    reduce(function, sequence[, initial])
    

    reduce() funciona llamando al function pasamos por los dos primeros elementos de la secuencia. El resultado devuelto por el function se usa en otra llamada a function junto con el siguiente (tercero en este caso), elemento.

    Este proceso se repite hasta que hayamos pasado por todos los elementos de la secuencia.

    El argumento opcional initial se utiliza, cuando est谩 presente, al comienzo de este “bucle” con el primer elemento en la primera llamada a function. En cierto modo, el initial elemento es el elemento 0, antes del primero, cuando se proporciona.

    reduce() es un poco m谩s dif铆cil de entender que map() y filter(), as铆 que veamos un ejemplo paso a paso:

    • Empezamos con una lista [2, 4, 7, 3] y pasar el add(x, y) funci贸n para reduce() junto a esta lista, sin un initial valor
    • reduce() llamadas add(2, 4)y add() devoluciones 6
    • reduce() llamadas add(6, 7) (resultado de la llamada anterior a add() y el siguiente elemento de la lista como par谩metros), y add() devoluciones 13
    • reduce() llamadas add(13, 3)y add() devoluciones 16
    • Como no quedan m谩s elementos en la secuencia, reduce() devoluciones 16

    La 煤nica diferencia, si hubi茅ramos dado un initial valor hubiera sido un paso adicional – 1.5. d贸nde reduce() Llamar铆a add(initial, 2) y usa ese valor de retorno en el paso 2.

    Sigamos adelante y usemos el reduce() funci贸n:

    from functools import reduce
    
    def add(x, y):
        return x + y
    
    list = [2, 4, 7, 3]
    print(reduce(add, list))
    

    Ejecutar este c贸digo producir铆a:

    16
    

    Nuevamente, esto podr铆a escribirse usando lambdas:

    from functools import reduce
    
    list = [2, 4, 7, 3]
    print(reduce(lambda x, y: x + y, list))
    print("With an initial value: " + str(reduce(lambda x, y: x + y, list, 10)))
    

    Y el c贸digo resultar铆a en:

    16
    With an initial value: 26
    

    Conclusi贸n

    Como se mencion贸 anteriormente, estas funciones son funciones de conveniencia. Est谩n ah铆 para que pueda evitar escribir un c贸digo m谩s engorroso, pero evite usar tanto ellos como las expresiones lambda demasiado.

    No fuerce estas herramientas porque “puede”, ya que a menudo puede generar un c贸digo ilegible que es dif铆cil de mantener. 脷selos solo cuando est茅 absolutamente claro lo que est谩 sucediendo tan pronto como observe la funci贸n o expresi贸n lambda.

    Si te das cuenta de que est谩s luchando por encajar la l贸gica necesaria en una map() funci贸n, o una expresi贸n lambda, es mucho mejor escribir un m茅todo for-loop / definido un poco m谩s largo y evitar confusiones innecesarias m谩s adelante.

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *