2012-07-09 5 views
6

map und filter sind oft austauschbar mit Listenkompressen, aber reduce ist nicht so leicht austauschbar wie map und filter (und außerdem bevorzuge ich in einigen Fällen immer noch die funktionale Syntax). Wenn Sie jedoch an den Argumenten selbst arbeiten müssen, gehe ich durch syntaktische Gymnastik und muss schließlich ganze Funktionen schreiben, um die Lesbarkeit zu erhalten.Können Sie eine Operation direkt auf Argumente in map/reduce/filter anwenden?

Ich werde map verwenden, um den Illustrationseinheitstest einfach zu halten, aber bedenken Sie bitte, dass reale Anwendungsfälle schwerer als Listenverständnis auszudrücken sind.

Ich habe zwei chaotische Wege gefunden, um darüber zu gehen, aber nichts, was ich jemals tatsächlich verwenden würde.

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

Gibt es einen markigen, eleganten Weg, die rechte Seite dieser Ausdrücke auszudrücken?

Antwort

11

Schauen Sie sich itertools für Werkzeuge an, die Ihnen das Leben erleichtern werden.

Beispielsweise ist der von Ihnen gepostete Code bereits als itertools.starmap verfügbar.

itertools.starmap(afunc, aniter) 

Aus der Dokumentation:

einen Iterator machen, dass die Funktion aus der iterable erhalten mit Argumenten berechnet. Wird anstelle von imap() verwendet, wenn Argumentparameter bereits in Tupeln aus einem einzelnen iterablen Objekt gruppiert sind (die Daten wurden "vor gezippt"). Der Unterschied zwischen imap() und starmap() entspricht der Unterscheidung zwischen Funktion (a, b) und Funktion (* c). Entspricht:

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

Es gibt auch Tonnen über andere Leckereien in itertools versteckt, so empfehle ich Ihnen, die Dokumentation durchlesen, um zu sehen, ob es gibt es noch etwas, dass Sie verwenden können. Der Abschnitt recipes zeigt außerdem Möglichkeiten auf, wie Sie die in itertools verfügbaren Funktionen zur Lösung einer Vielzahl von Problemen verwenden können. Auch wenn Sie kein Rezept finden, das Ihren genauen Anforderungen entspricht, können Sie einige der Ideen als Quelle der Inspiration nutzen.

+0

Schön, ich benutze IterTools die ganze Zeit, aber aus irgendeinem Grund ist es mir nicht eingefallen, dafür zu suchen. – kojiro

+0

+1 für die ausgezeichneten Rezepte Link! Das habe ich nie bemerkt – Kos