2012-07-09 1 views
6

map et filter sont souvent interchangeables avec la liste compréhensions, mais reduce n'est pas si facilement troqué comme map et filter (et d'ailleurs, dans certains cas, je préfère encore la syntaxe fonctionnelle de toute façon). Cependant, lorsque vous devez travailler sur les arguments eux-mêmes, je dois passer par la gymnastique syntaxique et devoir écrire des fonctions entières pour maintenir la lisibilité. Je vais utiliser map pour garder le test d'illustration simple, mais gardez à l'esprit que les cas d'utilisation réels peuvent être plus difficiles à exprimer en tant que compréhension de liste.Pouvez-vous appliquer une opération directement aux arguments dans map/reduce/filter?

J'ai trouvé deux façons désordonnées d'y arriver, mais rien que je n'utiliserais réellement.

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

Existe-t-il un moyen clair et élégant d'exprimer le côté droit de ces expressions?

Répondre

11

Consultez les itertools pour trouver les outils qui vous simplifieront la vie.

Par exemple, le code que vous avez publié est déjà disponible en tant que itertools.starmap.

itertools.starmap(afunc, aniter) 

De la documentation:

Faire une iterator qui calcule la fonction en utilisant des arguments obtenus à partir itérable. Utilisé à la place de imap() lorsque les paramètres d'argument sont déjà groupés en tuples à partir d'un seul itérable (les données ont été "pré-zippées"). La différence entre imap() et starmap() est parallèle à la distinction entre fonction (a, b) et fonction (* c). Équivalent à:

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

Il y a aussi des tonnes sur d'autres goodies cachés dans itertools, donc je vous recommande de lire dans la documentation pour voir s'il y a quelque chose là-bas que vous pouvez utiliser. La section recipes montre également comment vous pouvez utiliser les fonctions disponibles dans itertools pour résoudre divers problèmes. Même si vous ne trouvez pas une recette qui réponde exactement à vos besoins, il est probable que vous puissiez utiliser certaines des idées présentées comme source d'inspiration.

+0

Joli, j'utilise les outils tout le temps, mais pour une raison que j'ignore, il ne m'était pas venu à l'idée de chercher ça. – kojiro

+0

+1 pour l'excellent lien recettes! Je n'ai jamais remarqué ça – Kos

Questions connexes