Python Language
Lijst destructurering (ook bekend als in- en uitpakken)
Zoeken…
Vernietiging opdracht
Bij opdrachten kunt u een Iterable in waarden splitsen met behulp van de syntaxis "Uitpakken":
Destructurering als waarden
a, b = (1, 2)
print(a)
# Prints: 1
print(b)
# Prints: 2
Als u probeert meer dan de lengte van de iterable uit te pakken, krijgt u een foutmelding:
a, b, c = [1]
# Raises: ValueError: not enough values to unpack (expected 3, got 1)
Destructurering als een lijst
U kunt een lijst met onbekende lengte uitpakken met de volgende syntaxis:
head, *tail = [1, 2, 3, 4, 5]
Hier extraheren we de eerste waarde als een scalaire waarde en de andere waarden als een lijst:
print(head)
# Prints: 1
print(tail)
# Prints: [2, 3, 4, 5]
Dat is gelijk aan:
l = [1, 2, 3, 4, 5]
head = l[0]
tail = l[1:]
Het werkt ook met meerdere elementen of elementen aan het einde van de lijst:
a, b, *other, z = [1, 2, 3, 4, 5]
print(a, b, z, other)
# Prints: 1 2 5 [3, 4]
Negeren van waarden in destructuuropdrachten
Als u alleen geïnteresseerd bent in een bepaalde waarde, kunt u _
om aan te geven dat u niet geïnteresseerd bent. Opmerking: dit zal nog steeds _
, alleen de meeste mensen gebruiken het niet als variabele.
a, _ = [1, 2]
print(a)
# Prints: 1
a, _, c = (1, 2, 3)
print(a)
# Prints: 1
print(c)
# Prints: 3
Lijsten in destructuuropdrachten negeren
Ten slotte kunt u veel waarden negeren met de syntaxis *_
in de toewijzing:
a, *_ = [1, 2, 3, 4, 5]
print(a)
# Prints: 1
wat niet echt interessant is, omdat je in plaats daarvan indexering op de lijst zou kunnen gebruiken. Het wordt leuk om de eerste en laatste waarden in één opdracht te behouden:
a, *_, b = [1, 2, 3, 4, 5]
print(a, b)
# Prints: 1 5
of extraheer meerdere waarden tegelijk:
a, _, b, _, c, *_ = [1, 2, 3, 4, 5, 6]
print(a, b, c)
# Prints: 1 3 5
Verpakkingsfunctie argumenten
In functies kunt u een aantal verplichte argumenten definiëren:
def fun1(arg1, arg2, arg3):
return (arg1,arg2,arg3)
waardoor de functie alleen opvraagbaar wordt wanneer de drie argumenten worden gegeven:
fun1(1, 2, 3)
en u kunt de argumenten als optioneel definiëren door standaardwaarden te gebruiken:
def fun2(arg1='a', arg2='b', arg3='c'):
return (arg1,arg2,arg3)
dus je kunt de functie op veel verschillende manieren aanroepen, zoals:
fun2(1) → (1,b,c)
fun2(1, 2) → (1,2,c)
fun2(arg2=2, arg3=3) → (a,2,3)
...
Maar je kunt ook gebruik maken van de destructurering syntax om argumenten in te pakken, zodat u de variabelen met behulp van een kan toewijzen list
of dict
.
Een lijst met argumenten inpakken
Overweeg dat u een zoeklijst hebt
l = [1,2,3]
U kunt de functie met de zoeklijst als argument gebruiken met de syntaxis *
:
fun1(*l)
# Returns: (1,2,3)
fun1(*['w', 't', 'f'])
# Returns: ('w','t','f')
Maar als u geen lijst opgeeft waarvan de lengte overeenkomt met het aantal argumenten:
fun1(*['oops'])
# Raises: TypeError: fun1() missing 2 required positional arguments: 'arg2' and 'arg3'
Zoekwoordargumenten inpakken
Nu kunt u ook argumenten inpakken met behulp van een woordenboek. Je kunt de **
operator gebruiken om Python te vertellen het dict
te pakken als parameterwaarden:
d = {
'arg1': 1,
'arg2': 2,
'arg3': 3
}
fun1(**d)
# Returns: (1, 2, 3)
wanneer de functie alleen positionele argumenten heeft (die zonder standaardwaarden), moet het woordenboek alle verwachte parameters bevatten en geen extra parameter hebben, of krijg je een foutmelding:
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'
Voor functies met optionele argumenten kunt u de argumenten op dezelfde manier in een woordenboek opnemen:
fun2(**d)
# Returns: (1, 2, 3)
Maar daar kunt u waarden weglaten, omdat deze worden vervangen door de standaardwaarden:
fun2(**{'arg2': 2})
# Returns: ('a', 2, 'c')
En hetzelfde als voorheen, u kunt geen extra waarden opgeven die geen bestaande parameters zijn:
fun2(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4})
# Raises: TypeError: fun2() got an unexpected keyword argument 'arg4'
In het echte gebruik kunnen functies zowel positionele als optionele argumenten hebben, en het werkt hetzelfde:
def fun3(arg1, arg2='b', arg3='c')
return (arg1, arg2, arg3)
je kunt de functie oproepen met slechts een iterabele:
fun3(*[1])
# Returns: (1, 'b', 'c')
fun3(*[1,2,3])
# Returns: (1, 2, 3)
of met alleen een woordenboek:
fun3(**{'arg1':1})
# Returns: (1, 'b', 'c')
fun3(**{'arg1':1, 'arg2':2, 'arg3':3})
# Returns: (1, 2, 3)
of u kunt beide in hetzelfde gesprek gebruiken:
fun3(*[1,2], **{'arg3':3})
# Returns: (1,2,3)
Houd er echter rekening mee dat u niet voor hetzelfde argument meerdere waarden kunt opgeven:
fun3(*[1,2], **{'arg2':42, 'arg3':3})
# Raises: TypeError: fun3() got multiple values for argument 'arg2'
Uitpakken functieargumenten
Wanneer u een functie wilt maken die een willekeurig aantal argumenten kan accepteren en de positie of de naam van het argument niet wilt afdwingen tijdens het "compileren", is dit mogelijk en gaat u als volgt te werk:
def fun1(*args, **kwargs):
print(args, kwargs)
De parameters *args
en **kwargs
zijn speciale parameters die zijn ingesteld op respectievelijk een tuple
en een dict
:
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}
Als je naar voldoende Python-code kijkt, zul je snel ontdekken dat deze op grote schaal wordt gebruikt bij het doorgeven van argumenten aan een andere functie. Als u bijvoorbeeld de tekenreeksklasse wilt uitbreiden:
class MyString(str):
def __init__(self, *args, **kwarg):
print('Constructing MyString')
super(MyString, self).__init__(*args, **kwarg)