Entpacken, erweitertes Entpacken und verschachteltes erweitertes Entpacken
Betrachten diese Ausdrücke... Bitte haben Sie Geduld... das ist eine LANGE Liste...
(Anmerkung: einige Ausdrücke werden wiederholt-dies ist nur die Darstellung einer "Kontext")
a, b = 1, 2 # simple sequence assignment
a, b = ['green', 'blue'] # list asqignment
a, b = 'XY' # string assignment
a, b = range(1,5,2) # any iterable will do
# nested sequence assignment
(a,b), c = "XY", "Z" # a = 'X', b = 'Y', c = 'Z'
(a,b), c = "XYZ" # ERROR -- too many values to unpack
(a,b), c = "XY" # ERROR -- need more than 1 value to unpack
(a,b), c, = [1,2],'this' # a = '1', b = '2', c = 'this'
(a,b), (c,) = [1,2],'this' # ERROR -- too many values to unpack
# extended sequence unpacking
a, *b = 1,2,3,4,5 # a = 1, b = [2,3,4,5]
*a, b = 1,2,3,4,5 # a = [1,2,3,4], b = 5
a, *b, c = 1,2,3,4,5 # a = 1, b = [2,3,4], c = 5
a, *b = 'X' # a = 'X', b = []
*a, b = 'X' # a = [], b = 'X'
a, *b, c = "XY" # a = 'X', b = [], c = 'Y'
a, *b, c = "X...Y" # a = 'X', b = ['.','.','.'], c = 'Y'
a, b, *c = 1,2,3 # a = 1, b = 2, c = [3]
a, b, c, *d = 1,2,3 # a = 1, b = 2, c = 3, d = []
a, *b, c, *d = 1,2,3,4,5 # ERROR -- two starred expressions in assignment
(a,b), c = [1,2],'this' # a = '1', b = '2', c = 'this'
(a,b), *c = [1,2],'this' # a = '1', b = '2', c = ['this']
(a,b), c, *d = [1,2],'this' # a = '1', b = '2', c = 'this', d = []
(a,b), *c, d = [1,2],'this' # a = '1', b = '2', c = [], d = 'this'
(a,b), (c, *d) = [1,2],'this' # a = '1', b = '2', c = 't', d = ['h', 'i', 's']
*a = 1 # ERROR -- target must be in a list or tuple
*a = (1,2) # ERROR -- target must be in a list or tuple
*a, = (1,2) # a = [1,2]
*a, = 1 # ERROR -- 'int' object is not iterable
*a, = [1] # a = [1]
*a = [1] # ERROR -- target must be in a list or tuple
*a, = (1,) # a = [1]
*a, = (1) # ERROR -- 'int' object is not iterable
*a, b = [1] # a = [], b = 1
*a, b = (1,) # a = [], b = 1
(a,b),c = 1,2,3 # ERROR -- too many values to unpack
(a,b), *c = 1,2,3 # ERROR - 'int' object is not iterable
(a,b), *c = 'XY', 2, 3 # a = 'X', b = 'Y', c = [2,3]
# extended sequence unpacking -- NESTED
(a,b),c = 1,2,3 # ERROR -- too many values to unpack
*(a,b), c = 1,2,3 # a = 1, b = 2, c = 3
*(a,b) = 1,2 # ERROR -- target must be in a list or tuple
*(a,b), = 1,2 # a = 1, b = 2
*(a,b) = 'XY' # ERROR -- target must be in a list or tuple
*(a,b), = 'XY' # a = 'X', b = 'Y'
*(a, b) = 'this' # ERROR -- target must be in a list or tuple
*(a, b), = 'this' # ERROR -- too many values to unpack
*(a, *b), = 'this' # a = 't', b = ['h', 'i', 's']
*(a, *b), c = 'this' # a = 't', b = ['h', 'i'], c = 's'
*(a,*b), = 1,2,3,3,4,5,6,7 # a = 1, b = [2, 3, 3, 4, 5, 6, 7]
*(a,*b), *c = 1,2,3,3,4,5,6,7 # ERROR -- two starred expressions in assignment
*(a,*b), (*c,) = 1,2,3,3,4,5,6,7 # ERROR -- 'int' object is not iterable
*(a,*b), c = 1,2,3,3,4,5,6,7 # a = 1, b = [2, 3, 3, 4, 5, 6], c = 7
*(a,*b), (*c,) = 1,2,3,4,5,'XY' # a = 1, b = [2, 3, 4, 5], c = ['X', 'Y']
*(a,*b), c, d = 1,2,3,3,4,5,6,7 # a = 1, b = [2, 3, 3, 4, 5], c = 6, d = 7
*(a,*b), (c, d) = 1,2,3,3,4,5,6,7 # ERROR -- 'int' object is not iterable
*(a,*b), (*c, d) = 1,2,3,3,4,5,6,7 # ERROR -- 'int' object is not iterable
*(a,*b), *(c, d) = 1,2,3,3,4,5,6,7 # ERROR -- two starred expressions in assignment
*(a,b), c = 'XY', 3 # ERROR -- need more than 1 value to unpack
*(*a,b), c = 'XY', 3 # a = [], b = 'XY', c = 3
(a,b), c = 'XY', 3 # a = 'X', b = 'Y', c = 3
*(a,b), c = 'XY', 3, 4 # a = 'XY', b = 3, c = 4
*(*a,b), c = 'XY', 3, 4 # a = ['XY'], b = 3, c = 4
(a,b), c = 'XY', 3, 4 # ERROR -- too many values to unpack
Wie wollen Sie verstehen diese Komplexität und Verwirrung. Wie kann man immer RECHTS bei der Berechnung der Ergebnisse solcher Ausdrücke von hand. Oder beim Lesen von fremden code, sollte ich einfach ignorieren, und niemals versuchen zu ergründen, was der Ausdruck eigentlich?
InformationsquelleAutor der Frage treecoder | 2011-08-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich entschuldige mich für die Länge von diesem post, aber ich beschlossen, opt für die Vollständigkeit.
Sobald Sie wissen, ein paar grundlegende Regeln, es ist nicht schwer zu verallgemeinern. Ich werde mein bestes tun, zu erklären, mit ein paar Beispielen. Da Sie sprechen über die Bewertung dieser "von hand," ich werde vorschlagen, einige einfache substitution Regeln. Im Grunde, Sie finden es möglicherweise einfacher zu verstehen, ein Ausdruck, wenn alle iterables formatiert sind, in der gleichen Weise.
Für die Zwecke Auspacken nur folgende Ersetzungen gelten die auf der rechten Seite des
=
(d.h. für rvalues):Wenn Sie feststellen, dass ein Wert nicht zu bekommen, ausgepackt, dann wirst du die substitution rückgängig machen. (Siehe unten für weitere Erklärung.)
Auch, wenn Sie sehen "nackt" Kommas, vorgeben es gibt eine top-level-Tupel. Tun Sie dies auf der linken und der rechten Seite (also für lvalues und rvalues):
Mit diesen einfachen Regeln beachten, hier einige Beispiele:
Anwendung der oben genannten Regeln, wandeln wir
"XY"
zu('X', 'Y')
und decken die nackten Kommas in Klammern:Die visuelle Entsprechung hier macht es ziemlich offensichtlich, wie die Zuordnung funktioniert.
Hier ist eine fehlerhafte Beispiel:
Folgenden obige substitution Regeln, erhalten wir die folgenden:
Dies ist eindeutig falsch; der geschachtelte Strukturen nicht übereinstimmen. Lassen Sie uns nun sehen, wie es funktioniert für ein etwas komplexeres Beispiel:
Anwenden der oben aufgeführten Regeln erhalten wir
Aber jetzt ist es klar, von der Struktur, die
'this'
wird nicht entpackt, sondern direkt zugewiesenc
. Damit wir die substitution rückgängig machen.Nun wollen wir sehen, was passiert, wenn wir wickeln
c
in einem Tupel:Wird
Wieder, der Fehler ist offensichtlich.
c
ist nicht mehr ein nackter variable, sondern eine variable innerhalb einer Sequenz und damit die entsprechende Sequenz auf der rechten Seite ist ausgepackt in(c,)
. Aber die Sequenzen haben eine unterschiedliche Länge, so gibt es einen Fehler.Nun für längere Auspacken mit der
*
Betreiber. Dies ist ein wenig komplexer, aber es ist immer noch ziemlich einfach. Eine variable vorangestellt*
wird eine Liste, die enthält alle Elemente, die sich von der entsprechenden Sequenz, die nicht zugeordnet Variablen-Namen. Beginnend mit einem relativ einfachen Beispiel:Diese wird
Der einfachste Weg, um dies zu analysieren, ist die Arbeit von den enden.
'X'
zugeordnet ista
und'Y'
zugeordnet istc
. Die verbleibenden Werte in der Reihenfolge in eine Liste und zugeordnetb
.Lvalues wie
(*a, b)
und(a, *b)
sind nur Besondere Fälle der oben genannten. Sie können nicht zwei*
Betreiber in einem lvalue-Folge, denn es wäre nicht eindeutig. Wo würden die Werte gehen bei so etwas(a, *b, *c, d)
-- inb
oderc
? Ich werde betrachten Sie die eingebettete Fall in einem Augenblick.Hier der Fehler ist ziemlich selbsterklärend. Das Ziel (
*a
) müssen in einem Tupel.Dies funktioniert, weil es eine Nackte Komma. Die Anwendung der Regeln...
Da gibt es keine andere Variablen als
*a
*a
schlürft, bis alle Werte in der rvalue-Sequenz. Was ist, wenn Sie ersetzen die(1, 2)
mit einem einzigen Wert?wird
Wieder, der Fehler ist hier selbsterklärend. Sie kann nicht entpacken Sie etwas, das nicht eine Folge, und
*a
braucht etwas zum Auspacken. Also setzen wir es in eine ReihenfolgeIst eqivalent zu
Schließlich ist das ein gemeinsamer Punkt der Verwirrung:
(1)
ist das gleiche wie1
-- Sie müssen ein Komma zu unterscheiden, die ein Tupel aus einer arithmetischen Anweisung.Nun für den Nestbau. Eigentlich ist dieses Beispiel nicht in Ihrer "VERSCHACHTELTEN" Abschnitt; vielleicht haben Sie nicht erkennen, es war geschachtelte?
Wird
Den ersten Wert in der top-level-Tupel zugewiesen bekommt, und die restlichen Werte in der top-level-Tupel (
2
und3
) zugeordnet sindc
-- gerade, als wir erwarten sollten.Hab ich schon oben erklärt, warum die erste Zeile wirft ein Fehler. Die zweite Zeile ist albern, aber hier ist, warum es funktioniert:
Wie vorher erklärt, wir arbeiten von den enden.
3
zugeordnet istc
und dann die restlichen Werte zugeordnet sind, die variable mit der*
es vor, in diesem Fall(a, b)
. So entspricht das(a, b) = (1, 2)
was passiert, zu arbeiten, weil es die richtige Anzahl von Elementen. Ich kann nicht aus irgendeinem Grund denken, dies würde je in funktionierenden code. Ebensowird
Arbeiten von den enden
's'
zugeordnet istc
und('t', 'h', 'i')
zugeordnet ist(a, *b)
. Wieder arbeiten von den enden't'
zugeordnet ista
und('h', 'i')
zugeordnet ist b als a-Liste. Dies ist ein weiteres dummes Beispiel, sollte nie erscheinen in funktionierenden code.InformationsquelleAutor der Antwort senderle
Ich finde den Python-2-Tupel Auspacken ziemlich einfach. Jeder name auf der linken Seite entspricht, entweder eine gesamte Sequenz oder eine einzelne Position in einer Sequenz auf der rechten Seite. Wenn Namen entsprechen einzelne Elemente jeder Folge, dann muss es genug Namen, um alle Elemente.
Erweitert Auspacken, jedoch kann sicherlich verwirrend sein, weil es so mächtig ist. Die Realität ist, Sie sollten nie tun, die letzten 10 oder mehr gültige Beispiele, die Sie Gaben-wenn die Daten, die strukturiert ist, sollte es in einem
dict
oder eine Instanz der Klasse, nicht unstrukturierte Formen, wie Listen.Klar, die neue syntax missbraucht werden können. Die Antwort auf Ihre Frage ist, dass Sie sollte nicht zu Lesen, die Ausdrücke wie, - Sie sind schlechte Praxis, und ich bezweifle, dass Sie genutzt werden.
Nur weil Sie schreiben können beliebig komplexe Ausdrücke, bedeutet nicht, Sie sollten. Sie können code schreiben, wie
map(map, iterable_of_transformations, map(map, iterable_of_transformations, iterable_of_iterables_of_iterables))
aber Sie nicht.InformationsquelleAutor der Antwort agf
Ich Sie glauben, Ihr code möglicherweise irreführende Verwendung einer anderen form zu verleihen.
Es ist wie mit zusätzlichen Klammern in Ausdrücken zu vermeiden, Fragen über Operatoren Vorrang.
I ' TS immer eine gute Investition, um Ihren code lesbar.
Ich lieber mit Auspacken nur für einfache Aufgaben wie swap.
InformationsquelleAutor der Antwort Michał Šrajer