Frage

Hat Karte () durchläuft die Liste wie „für“ würde? Gibt es einen Wert im Umgang mit Karte vs für?

Wenn ja, jetzt mein Code sieht wie folgt aus:

for item in items:
    item.my_func()

Wenn es Sinn macht, würde Ich mag es (machen Karte). Ist das möglich? Was ist ein Beispiel, wie?

War es hilfreich?

Lösung

Sie könnten verwenden map anstelle der for Schleife Sie‘ ve gezeigt, aber da Sie nicht das Ergebnis von item.my_func() zu verwenden scheinen, ist dies nicht empfohlen . map sollte verwendet werden, wenn Sie eine Funktion ohne Nebenwirkungen auf alle Elemente einer Liste anwenden möchten. In allen anderen Fällen, eine explizite for-Schleife verwenden.

Auch, wie von Python 3.0 map gibt einen Generator, so dass in diesem Fall map nicht gleich verhalten (es sei denn, Sie explizit alle Elemente durch den Generator, zB durch den Aufruf list darauf).


Bearbeiten : kibibu fragt in den Kommentaren für eine Klarstellung darüber, warum erste Argument der map sollte keine Funktion mit Nebenwirkungen. Ich gebe diese Frage einen Schuss zu beantworten:

map soll eine Funktion übergeben werden f im mathematischen Sinne . Unter solchen Umständen ist es egal, in welcher Reihenfolge f auf die Elemente des zweiten Arguments angewandt wird (solange sie zurück in ihrer ursprünglichen Reihenfolge, natürlich). Noch wichtiger ist, ist semantisch äquivalent map(g, map(f, l)) unter diesen Umständen zu map(lambda x: g(f(x)), l), unabhängig von der Reihenfolge, in der f und g an ihre jeweiligen Eingänge angelegt werden .

z. B., ist es egal, ob map zurückkehrt und Iterator oder eine vollständige Liste auf einmal. Wenn jedoch f und / oder g Nebenwirkungen verursachen, dann ist diese Äquivalenz nur dann, wenn die Semantik von map(g, map(f, l)) ist so, dass in jeder Phase g auf den ersten aufgebracht wird, gewährleistet ist n Elemente von map(f, l) zurück vor map(f, l) gilt f zum (n + 1) st Elemente l. (Was bedeutet, dass map die faulste möglich Iteration durchführen muß, ---, die es in Python tut 3, aber nicht in Python 2!)

Einen Schritt weiter gehen: selbst wenn wir den Python 3 Implementierung von map, die semantischen Äquivalenz kann leicht brechen, wenn die Ausgabe von map(f, l) nehmen ist z.B. durchlaufen itertools.tee bevor sie an den äußeren map Anruf zugeführt wird.

Die obige Erörterung kann aus einer theoretischen Natur erscheinen, aber als Programme immer komplexer werden, werden sie schwieriger zu Grunde zu und deshalb schwieriger zu debuggen. Um sicherzustellen, dass einige Dinge unveränderlich sind mildert dieses Problem etwas, und kann in der Tat eine ganze Klasse von Fehlern verhindern.

Schließlich erinnert map viele Menschen seiner wirklich funktionierenden Gegenstück in verschiedenen (rein) funktionalen Sprachen. Passing es sich um eine „Funktion“ mit Nebenwirkungen werden die Menschen verwirren. Daher wird als Alternative zu sehen (das heißt, eine explizite Schleife) als ein Anruf zu implementieren, nicht schwerer zu map, ist es sehr empfehlenswert, dass eine Verwendung von map auf die Fälle, in denen beschränkt die Funktion angewandt werden, keine Nebenwirkungen verursachen, .

Andere Tipps

Sie können diese mit der Karte wie folgt schreiben:

map(cls.my_func, items)

ersetzt cls mit der Klasse der Elemente, die Sie iterieren.

Wie Stephan202 erwähnt, ist dies nicht empfohlen in diesem Fall.

In der Regel, wenn Sie eine neue Liste erstellen möchten, indem Sie eine Funktion zu jedem Element in der Liste Anwendung verwenden Karte. Dies hat den implizit was bedeutet, dass die Funktion keine Nebenwirkung hat, und somit könnten Sie (möglicherweise) die Karte parallel ausgeführt werden.

Wenn Sie nicht wollen, eine neue Liste zu erstellen, oder wenn die Funktion Nebenwirkungen hat, verwenden Sie eine for-Schleife. Dies ist der Fall in Ihrem Beispiel.

Es gibt einen leichten semantischen Unterschied, die wahrscheinlich in Python Sprache spec geschlossen ist. Die Karte ist explizit parallelizable, während für nur in besonderen Situationen. Code kann brechen aus für , sondern nur die Flucht mit Ausnahme von Karte .

Meiner Meinung nach Karte sollte nicht auch die Reihenfolge der Funktionsanwendung garantieren, während für Muss. AFAIK keine Python-Implementierung ist derzeit der Lage, diese Auto-Parallelisierung zu tun.

Sie können Ihre map bis zu einem gewissen kühlen Gewinde- oder Multiprozessing OR Distributed Computing Framework wechseln, wenn Sie benötigen. Disco ist ein Beispiel für verteilte, widerstandsfähig gegen Ausfälle Erlang-and-Python-basierten Rahmen. Ich baut es auf 2 Boxen von 8 Cores und jetzt ist mein Programm läuft 16 mal schneller, dank der Disco-Cluster, jedoch hatte ich mein Programm aus der Liste Comprehensions neu zu schreiben und für Schleifen zur Karte / reduzieren.

Es ist das gleiche Angebot, ein Programm mit for-Schleifen und Listenkomprehensionen und Karte / reduzieren, zu schreiben, aber wenn Sie sie brauchen auf einem Cluster ausgeführt werden, Sie können es fast kostenlos, wenn Sie Karte verwendet / reduzieren. Wenn Sie nicht das, na ja, Sie werden neu schreiben müssen.

Achtung: soweit ich weiß, Python 2.x eine Liste anstelle eines Iterators von Karte zurückgibt. Ich habe gehört, kann dies durch die Verwendung iter.imap() umgangen wird (nie benutzt obwohl).

Verwenden Sie eine explizite for-Schleife, wenn Sie nicht über eine Liste der Ergebnisse müssen zurück (z. B. Funktionen mit Nebenwirkungen).

eine Liste Verständnis, wenn Sie eine Liste der Ergebnisse müssen Sie zurück (z. B. Funktionen, die einen Wert basiert direkt auf den Eingang zurück).

Mit der Karte (), wenn Sie versuchen, Lisp Benutzer zu überzeugen, dass Python wert ist verwenden. ;)

Der Hauptvorteil von map ist, wenn Sie das Ergebnis einer Berechnung auf jedes Element in einer Liste erhalten möchten. Zum Beispiel verdoppelt sich diese Schnipsel jeden Wert in einer Liste:

map(lambda x: x * 2, [1,2,3,4])  #=> [2, 4, 6, 8]

Es ist wichtig, dass map gibt eine neue Liste mit den Ergebnissen zu beachten. Es ist nicht die ursprüngliche Liste anstelle ändern.

Um mit for das gleiche zu tun, würden Sie eine leere Liste erstellen müssen und eine zusätzliche Zeile zum for Körper fügen Sie das Ergebnis jeder Berechnung der neuen Liste hinzuzufügen. Die map Version ist prägnanter und funktional.

Karte kann manchmal schneller für integrierte Funktionen als manuell eine Codierung für Schleife. Versuchen Sie Timing-Karte (str, Bereich (1000000)) im Vergleich zu einem ähnlichen for-Schleife.

map(lambda item: item.my_func(), items)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top