2012-07-09 5 views
6

map y filter son a menudo intercambiables con listas de comprensión, pero reduce no se reemplaza tan fácilmente como map y filter (y además, en algunos casos, prefiero la sintaxis funcional de todos modos). Sin embargo, cuando necesitas operar con los argumentos, me encuentro realizando gimnasia sintáctica y eventualmente tengo que escribir funciones enteras para mantener la legibilidad.¿Se puede aplicar una operación directamente a argumentos dentro del mapa/reducir/filtrar?

Voy a usar map para mantener la ilustración de la prueba de unidad simple, pero tenga en cuenta que los casos de uso de la vida real pueden ser más difíciles de expresar como una lista de comprensión.

He encontrado dos maneras complicadas de hacerlo, pero nada que alguna vez realmente use.

[afunc(*i) for i in aniter] == map(afunc, *zip(*aniter)) 
[afunc(*i) for i in aniter] == map(lambda i: apply(afunc, i), aniter) 

¿Hay alguna forma concisa y elegante de expresar el lado derecho de estas expresiones?

Respuesta

11

Consulte itertools para obtener herramientas que le harán la vida más fácil.

Por ejemplo, el código que ha publicado ya está disponible como itertools.starmap.

itertools.starmap(afunc, aniter) 

De la documentación:

Hacer un iterador que calcula la función con argumentos obtenidos de la iterable. Se usa en lugar de imap() cuando los parámetros del argumento ya están agrupados en tuplas desde un único iterable (los datos han sido "preincronizados"). La diferencia entre imap() y starmap() es paralela a la distinción entre función (a, b) y función (* c). Equivalente a:

def starmap(function, iterable): 
    # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000 
    for args in iterable: 
     yield function(*args) 

También hay toneladas más de otras golosinas escondidas en itertools, por lo que recomiendo que lea la documentación para ver si hay algo más ahí que usted puede utilizar. La sección recipes también muestra formas en que puede usar las funciones disponibles en itertools para resolver una variedad de problemas. Incluso si no puede encontrar una receta que resuelva sus requisitos exactos, es probable que pueda usar algunas de las ideas demostradas como fuente de inspiración.

+0

Agradable, uso itertools todo el tiempo, pero por alguna razón no se me ocurrió buscar esto. – kojiro

+0

+1 para el excelente enlace de recetas Nunca me di cuenta de eso – Kos

Cuestiones relacionadas