Python Language
List Destructuring (auch bekannt als Ein- und Auspacken)
Suche…
Zerstörungsauftrag
In Zuweisungen können Sie eine Iterable mit der Syntax "Unpacking" in Werte aufteilen:
Zerstörung als Werte
a, b = (1, 2)
print(a)
# Prints: 1
print(b)
# Prints: 2
Wenn Sie versuchen, mehr als die Länge des Iterationsprogramms zu entpacken, wird eine Fehlermeldung angezeigt:
a, b, c = [1]
# Raises: ValueError: not enough values to unpack (expected 3, got 1)
Zerstörung als Liste
Sie können eine Liste unbekannter Länge mit der folgenden Syntax entpacken:
head, *tail = [1, 2, 3, 4, 5]
Hier extrahieren wir den ersten Wert als Skalar und die anderen Werte als Liste:
print(head)
# Prints: 1
print(tail)
# Prints: [2, 3, 4, 5]
Welches ist äquivalent zu:
l = [1, 2, 3, 4, 5]
head = l[0]
tail = l[1:]
Es funktioniert auch mit mehreren Elementen oder Elementen am Ende der Liste:
a, b, *other, z = [1, 2, 3, 4, 5]
print(a, b, z, other)
# Prints: 1 2 5 [3, 4]
Werte in Destructuring-Zuweisungen ignorieren
Wenn Sie nur an einem bestimmten Wert interessiert sind, können Sie mit _
angeben, dass Sie nicht interessiert sind. Hinweis: Dies wird immer noch _
, nur verwenden die meisten Leute es nicht als Variable.
a, _ = [1, 2]
print(a)
# Prints: 1
a, _, c = (1, 2, 3)
print(a)
# Prints: 1
print(c)
# Prints: 3
Ignorieren von Listen in Zerstörungszuweisungen
Schließlich können Sie viele Werte mit der *_
Syntax in der Zuweisung ignorieren:
a, *_ = [1, 2, 3, 4, 5]
print(a)
# Prints: 1
Das ist nicht wirklich interessant, da Sie stattdessen die Indexierung auf der Liste verwenden könnten. Wo es schön wird, ist, die ersten und letzten Werte in einer Aufgabe zu behalten:
a, *_, b = [1, 2, 3, 4, 5]
print(a, b)
# Prints: 1 5
oder mehrere Werte auf einmal extrahieren:
a, _, b, _, c, *_ = [1, 2, 3, 4, 5, 6]
print(a, b, c)
# Prints: 1 3 5
Argumente für Verpackungsfunktionen
In Funktionen können Sie eine Reihe von obligatorischen Argumenten definieren:
def fun1(arg1, arg2, arg3):
return (arg1,arg2,arg3)
Dadurch wird die Funktion nur dann aufrufbar, wenn die drei Argumente angegeben werden:
fun1(1, 2, 3)
Sie können die Argumente als optional definieren, indem Sie Standardwerte verwenden:
def fun2(arg1='a', arg2='b', arg3='c'):
return (arg1,arg2,arg3)
So können Sie die Funktion auf viele verschiedene Arten aufrufen:
fun2(1) → (1,b,c)
fun2(1, 2) → (1,2,c)
fun2(arg2=2, arg3=3) → (a,2,3)
...
Sie können die Destruktursyntax jedoch auch verwenden, um Argumente zu packen , sodass Sie Variablen mithilfe einer list
oder eines dict
zuweisen können.
Eine Liste mit Argumenten packen
Stellen Sie sich vor, Sie haben eine Liste von Werten
l = [1,2,3]
Sie können die Funktion mit der Liste der Werte als Argument mit der *
-Syntax aufrufen:
fun1(*l)
# Returns: (1,2,3)
fun1(*['w', 't', 'f'])
# Returns: ('w','t','f')
Wenn Sie jedoch keine Liste bereitstellen, deren Länge der Anzahl der Argumente entspricht:
fun1(*['oops'])
# Raises: TypeError: fun1() missing 2 required positional arguments: 'arg2' and 'arg3'
Schlüsselwortargumente packen
Jetzt können Sie Argumente auch mithilfe eines Wörterbuchs packen. Mit dem Operator **
können Sie Python anweisen, das dict
als Parameterwerte zu entpacken:
d = {
'arg1': 1,
'arg2': 2,
'arg3': 3
}
fun1(**d)
# Returns: (1, 2, 3)
Wenn die Funktion nur Positionsargumente hat (diejenigen ohne Standardwerte), müssen Sie das Wörterbuch mit allen erwarteten Parametern enthalten und keine zusätzlichen Parameter haben.
fun1(**{'arg1':1, 'arg2':2})
# Raises: TypeError: fun1() missing 1 required positional argument: 'arg3'
fun1(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4})
# Raises: TypeError: fun1() got an unexpected keyword argument 'arg4'
Für Funktionen mit optionalen Argumenten können Sie die Argumente auf dieselbe Weise als Wörterbuch packen:
fun2(**d)
# Returns: (1, 2, 3)
Dort können Sie jedoch Werte weglassen, da diese durch die Standardwerte ersetzt werden:
fun2(**{'arg2': 2})
# Returns: ('a', 2, 'c')
Und wie zuvor können Sie keine zusätzlichen Werte angeben, die keine vorhandenen Parameter sind:
fun2(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4})
# Raises: TypeError: fun2() got an unexpected keyword argument 'arg4'
In der Praxis können Funktionen sowohl positionelle als auch optionale Argumente haben, und es funktioniert gleich:
def fun3(arg1, arg2='b', arg3='c')
return (arg1, arg2, arg3)
Sie können die Funktion nur mit einem iterierbaren Aufruf aufrufen:
fun3(*[1])
# Returns: (1, 'b', 'c')
fun3(*[1,2,3])
# Returns: (1, 2, 3)
oder nur mit einem Wörterbuch:
fun3(**{'arg1':1})
# Returns: (1, 'b', 'c')
fun3(**{'arg1':1, 'arg2':2, 'arg3':3})
# Returns: (1, 2, 3)
oder Sie können beide im selben Anruf verwenden:
fun3(*[1,2], **{'arg3':3})
# Returns: (1,2,3)
Beachten Sie jedoch, dass Sie nicht mehrere Werte für dasselbe Argument angeben können:
fun3(*[1,2], **{'arg2':42, 'arg3':3})
# Raises: TypeError: fun3() got multiple values for argument 'arg2'
Funktionsargumente auspacken
Wenn Sie eine Funktion erstellen möchten, die eine beliebige Anzahl von Argumenten akzeptieren kann und die Position oder den Namen des Arguments nicht zum Zeitpunkt des "Kompilierens" erzwingen soll, ist dies möglich.
def fun1(*args, **kwargs):
print(args, kwargs)
Die Parameter *args
und **kwargs
sind spezielle Parameter, die auf ein tuple
bzw. ein dict
sind:
fun1(1,2,3)
# Prints: (1, 2, 3) {}
fun1(a=1, b=2, c=3)
# Prints: () {'a': 1, 'b': 2, 'c': 3}
fun1('x', 'y', 'z', a=1, b=2, c=3)
# Prints: ('x', 'y', 'z') {'a': 1, 'b': 2, 'c': 3}
Wenn Sie sich genügend Python-Code anschauen, werden Sie schnell feststellen, dass er häufig verwendet wird, wenn Sie Argumente an eine andere Funktion übergeben. Zum Beispiel, wenn Sie die String-Klasse erweitern möchten:
class MyString(str):
def __init__(self, *args, **kwarg):
print('Constructing MyString')
super(MyString, self).__init__(*args, **kwarg)