Me gustaría aprender a usar map / reduce / filter más; ¿donde debería empezar?

La mayoría de las comprensiones de listas se pueden escribir en una operación de mapa o filtro. Entonces, si ya es competente en la comprensión de la lista de Python, entonces ya conoce la lógica necesaria para usar el mapa y el filtro correctamente, y ya está encontrando usos para el mapa y el filtro.

ejemplo de mapa

def square(x): return x*x squares1 = [square(x) for x in xrange(10)] # using a list comprehension squares2 = map(square, xrange(10)] # using the map function print squares1 # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] print squares2 # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

ejemplo de filtro

 def is_odd(x): return x & 1 == 1 odds1 = [x for x in xrange(10) if is_odd(x)] # list comprehension odds2 = filter(is_odd, xrange(10)) print odds1 # [1, 3, 5, 7, 9] print odds2 # [1, 3, 5, 7, 9] 

En la práctica, nunca he necesitado realmente usar filtro, pero una forma inteligente de encontrar un uso para reducir es implementar la función de suma para una lista de objetos cuya salida agregada no es un número entero.

El uso de la función sum en python siempre devuelve un número. Sin embargo, ¿qué sucede si desea agregar objetos en Python que no devuelven un número entero?

Tome colecciones. Contador por ejemplo. Cuando se suman dos de estos objetos, se obtiene una adición puntual, como si fueran vectores matemáticos.

 import collections c1 = collections.Counter(dict(a=1, b=2, c=3)) c2 = collections.Counter(dict(a=1, b=2, c=3)) c3 = c1 + c2 print c3 # Counter({'c': 6, 'b': 4, 'a': 2}) 

Sin embargo, si tuviera una lista de estos objetos y tratara de usar la función de suma, fallaría horriblemente. Sin embargo, lo que puede hacer para evitar esto es utilizar la función de reducción.

 counters = [c1, c2] def sum_with_reduce(objects): # operator.iadd is the same as lambda x, y: x+y return reduce(operator.iadd, objects) sum_counters = sum_with_reduce(counters) print sum_counters # Counter({'c': 6, 'b': 4, 'a': 2}) # another example of joining string objects pokemon = ['p', 'o', 'k', 'e', 'm', 'o', 'n'] # sum(pokemon) fails, but this works print sum_with_reduce(pokemon) # "pokemon" 

Ahora puedes sumar sobre objetos arbitrarios, supongo que es algo.

Realmente comencé a usar los builtins funcionales y las lambdas después de probar los lenguajes puramente funcionales. Pasé una buena cantidad de tiempo de juego aprendiendo Haskell, un lenguaje en el que usar construcciones como mapear, reducir y filtrar es la norma. Echa un vistazo a un lenguaje funcional como Haskell o Erlang.

Mapear, reducir y filtrar son ejemplos de aplicaciones de funciones de orden superior. Investigue un poco sobre el cálculo lambda para obtener más antecedentes matemáticos.

Editar: más prácticamente, necesita experimentar con estas funciones. Solo juega en ipython. Lea también el código de otras personas.