Erfahren Sie, warum `map()` und List Comprehensions in Python unterschiedliche Ergebnisse liefern, bedingt durch Closures und Auswertungszeitpunkt.
---
Dieses Video basiert auf der Frage https://stackoverflow.com/q/139819/ gestellt von dem Nutzer 'jfs' ( https://stackoverflow.com/u/4279/ ) sowie auf der Antwort https://stackoverflow.com/a/139899/ bereitgestellt von dem Nutzer 'Torsten Marek' ( https://stackoverflow.com/u/9567/ ) auf der Website 'Stack Overflow'. Vielen Dank an diese großartigen Nutzer und die Stackexchange-Community für ihre Beiträge.
Besuchen Sie diese Links, um den Originalinhalt und weitere Details zu sehen, z. B. alternative Lösungen, aktuelle Entwicklungen zum Thema, Kommentare, Versionsverlauf usw. Der ursprüngliche Titel der Frage lautete beispielsweise: Why results of map() and list comprehension are different?
Außerdem steht der Inhalt (außer Musik) unter der Lizenz CC BY-SA https://meta.stackexchange.com/help/l...
Der ursprüngliche Fragenbeitrag steht unter der Lizenz 'CC BY-SA 2.5' ( https://creativecommons.org/licenses/... ), und der ursprüngliche Antwortbeitrag steht unter der Lizenz 'CC BY-SA 2.5' ( https://creativecommons.org/licenses/... ).
Falls Ihnen irgendetwas auffällt oder Unstimmigkeiten bestehen, schreiben Sie mir bitte an vlogize [AT] gmail [DOT] com.
---
Verstehen der Unterschiede zwischen map() und List Comprehensions in Python
Beim Programmieren in Python sind Ihnen möglicherweise Situationen begegnet, in denen das Verhalten von map() und List Comprehensions unerwartete Ergebnisse liefert. Besonders das Verhalten kann sich ändern, je nachdem, wie Closures und die Bindung von Variablen gehandhabt werden. Dieser Blogbeitrag analysiert die Feinheiten der Verwendung von map() im Vergleich zu List Comprehensions, mit einem besonderen Fokus darauf, wie sie in bestimmten Szenarien unterschiedliche Ausgaben erzeugen können.
Das Problem: Ergebnisse von map() vs. List Comprehensions
Betrachten wir die folgende einfache Funktion, die in Python definiert ist:
[[Siehe Video, um diesen Text oder Codeausschnitt anzuzeigen]]
Diese Funktion soll, wenn sie eine Sammlung von Lambda-Funktionen übergeben bekommt, diese Funktionen ausführen und deren Ergebnisse ausgeben. Allerdings kann folgendes Testbeispiel das Problem verdeutlichen:
[[Siehe Video, um diesen Text oder Codeausschnitt anzuzeigen]]
Wie in den Tests ersichtlich, gibt es bemerkenswerte Unterschiede bei den Ausgaben der Funktion bei Verwendung von map und List Comprehensions. Warum also entstehen diese unterschiedlichen Ergebnisse?
Die Erklärung: Closures und Variablenbindung
Der Kern des Problems liegt darin, wie Closures in Python die Variablenbindung handhaben. Hier eine detaillierte Aufschlüsselung dessen, was passiert:
1. Lazy Evaluation bei Lambdas
Was passiert? Die Werte von i in den Lambda-Ausdrücken werden „faul“ (lazy) ausgewertet. Das bedeutet, sie werden erst dann ausgewertet, wenn die Funktion (in diesem Fall f) sie aufruft.
Auswirkung: Wenn die Lambdas innerhalb der Funktion aufgerufen werden, beziehen sie sich auf die Variable i, die zu diesem Zeitpunkt bereits den zuletzt angenommenen Wert hält, nämlich -1. Folglich liefern alle Lambdas -1 zurück statt der erwarteten Werte.
2. List Comprehensions vs. Generator Expressions
Der Unterschied zwischen List Comprehensions und Generator Expressions zeigt sich darin, wie sie die Variablen-Skopierung handhaben.
Bei einer List Comprehension wird die Schleifenvariable im umgebenden Scope gebunden, im Gegensatz zu einer Generator Expression, die die Variable temporär bindet.
[[Siehe Video, um diesen Text oder Codeausschnitt anzuzeigen]]
Als Ergebnis zeigen sowohl die List Comprehension als auch die Generator Expression verschiedene Resultate, wenn sie nach Abschluss der Schleife ausgewertet werden, aufgrund der gleichen Closure-Erfassungsmechanik.
3. Korrektur des Verhaltens mit Default-Argument-Tricks
Um sicherzustellen, dass jede Lambda den Wert von i zum Zeitpunkt ihrer Erzeugung festhält, können Sie die Lambda-Funktionen folgendermaßen modifizieren:
[[Siehe Video, um diesen Text oder Codeausschnitt anzuzeigen]]
Diese Technik bindet effektiv den aktuellen Wert von i an u und stellt sicher, dass beim späteren Aufruf der Lambda-Funktion der Wert korrekt erhalten bleibt und ausgegeben wird.
Fazit: Wichtige Erkenntnisse
Variablenbindung ist entscheidend: Das Verständnis, wie Python Variablen-Scope und Closures handhabt, ist entscheidend, um solche Fallstricke zu vermeiden.
Unterschiedliche Ausgaben erfordern unterschiedliche Techniken: Je nachdem, ob Sie map(), List Comprehensions oder Generator Expressions verwenden, führen verwendete Techniken zu unterschiedlichen Ergebnissen.
Nutzen von Default-Argumenten: Verwenden Sie Standard-Argumente in Lambdas, um aktuelle Schleifenwerte effektiv zu erfassen.
Wenn Sie diese Konzepte und die Funktionsweise von Closures in Python verstanden haben, können Sie bessere und sicherere P
Информация по комментариям в разработке