Warum verwenden Generator-Ausdrücke und Dict / Set-Comprehensions in Python 2 im Gegensatz zu Listen-Comprehensions eine verschachtelte Funktion?

8

Listen-Comprehensions haben ihren Code direkt in der Funktion, wo sie verwendet werden, wie folgt:

%Vor%

Während Generator-Ausdrücke und Dict / Set-Comprehensions meist in einer separaten geschachtelten Funktion platziert sind, wie folgt:

%Vor%

In Python 3 werden alle davon in eine verschachtelte Funktion eingefügt.

Warum wird der Code in einer separaten verschachtelten Funktion platziert? Ich erinnere mich vage daran, etwas über Leute gelesen zu haben, die Verständnis und / oder Genexpr-Variablen reparieren wollten, die vor langer Zeit in den umgebenden Bereich fielen, war das die Lösung für das oder so?

Warum werden Listenkompressen anders als in Python 2 implementiert? Wegen der Rückwärtskompatibilität? (I dachte Ich habe das Gespräch über die Verschüttung gehört, die viel nach der Einführung von Generatorausdrücken behoben wurde, aber ich könnte gerade wirklich alte Diskussionen oder etwas gelesen haben)

    
Aleksi Torhamo 22.10.2014, 04:27
quelle

1 Antwort

10

Ja, Sie haben Recht. In Python 3.x wird dies eingeführt, um den Variablenverlust zu beheben. Zitat aus dem Post von Geschichte des Python-Blogs , angeblich geschrieben vom BDFL selbst,

  

Wir haben auch eine weitere Änderung in Python 3 vorgenommen, um die Äquivalenz zwischen Listenerläuterungen und Generatorausdrücken zu verbessern. In Python 2 "leckt" das Listenverständnis die Schleifenkontrollvariable in den umgebenden Bereich :

%Vor%      

Dies war ein Artefakt der ursprünglichen Implementierung von List Comprehensions; es war jahrelang eines von Pythons "schmutzigen kleinen Geheimnissen". Es begann als ein bewusster Kompromiss, um die Listen verständlich zu machen, und obwohl es kein gewöhnlicher Fallstrick für Anfänger war, stach es auf jeden Fall gelegentlich Leute. Für Generatorausdrücke konnten wir dies nicht tun. Generatorausdrücke werden unter Verwendung von Generatoren implementiert, deren Ausführung einen separaten Ausführungsrahmen erfordert. Daher waren Generator-Ausdrücke (besonders wenn sie über eine kurze Sequenz iterieren) weniger effizient als Listen-Comprehensions.

     

Allerdings haben wir uns in Python 3 entschieden, das "schmutzige kleine Geheimnis" der Listenkompromittierungen zu beheben, indem wir die gleiche Implementierungsstrategie wie für Generatorausdrücke verwenden . Daher wird in Python 3 das obige Beispiel (nach der Änderung von print(x) :-): 'davor' gedruckt, was beweist, dass das 'x' im Listenverständnis temporär Schatten wirft, aber das 'x' im umgebenden Bereich nicht überschreibt .

Alle Ihre Fragen werden durch den hervorgehobenen Text beantwortet.

    
thefourtheye 22.10.2014, 04:38
quelle