Hogyan kell használni a kicsomagoló operátorokat (*, **) a Pythonban?

A Python a leggyakrabban használt programozási nyelv. Ma megtanulod használni az egyik alapvető – de gyakran figyelmen kívül hagyott – funkcióját, a kicsomagolást Pythonban.

Valószínűleg láttad a * és a ** jeleket mások kódjában, vagy akár használtad is anélkül, hogy tudnád, mi a céljuk. Végigjárjuk a kicsomagolás fogalmát, és azt, hogyan használhatjuk fel további Pythonic kódok írásához.

Íme egy lista azokról a fogalmakról, amelyeket hasznosnak talál az oktatóanyag olvasása közben:

  • Iterálható: Bármilyen szekvencia, amely for-hurokkal ismételhető, például halmazok, listák, sorok és szótárak
  • Meghívható: Egy Python-objektum, amely dupla zárójellel () hívható meg, például myfunction()
  • Shell: Interaktív futási környezet, amely lehetővé teszi Python kód futtatását. Úgy hívhatjuk, hogy terminálban futtatjuk a „python”-t
  • Változó: Szimbolikus név, amely egy objektumot tárol, és rendelkezik lefoglalt memóriahellyel.

Kezdjük a leggyakoribb zavarral: A Python csillagjegyei egyben aritmetikai operátorok is. Egy csillag

szorzásra szolgál, míg kettő (**) hatványozásra vonatkozik.

>>> 3*3
9
>>> 3**3
27

Ezt úgy tudjuk bebizonyítani, hogy megnyitunk egy Python shellt és beírjuk:

Megjegyzés: Az oktatóanyag követéséhez telepítenie kell a Python 3-at. Ha még nincs telepítve, tekintse meg Python telepítési útmutatónkat.

Amint látja, a csillagot az első szám után és a második előtt használjuk. Ha ezt látja, az azt jelenti, hogy az aritmetikai operátorokat használjuk.

>>> *range(1, 6),
(1, 2, 3, 4, 5)
>>> {**{'vanilla':3, 'chocolate':2}, 'strawberry':2}
{'vanilla': 3, 'chocolate': 2, 'strawberry': 2}

Másrészről a csillagokat (*, **) használjuk az iterálás előtt a kicsomagoláshoz – például:

Ne aggódjon, ha nem kapja meg, ez csak egy bevezető a Pythonban való kicsomagoláshoz. Tehát folytassa és olvassa el a teljes bemutatót!

Mi a kicsomagolás?

A kicsomagolás a cuccok – iterálható elemek, például listák, sorok és szótárak – eltávolításának folyamata. Tekintsd úgy, mintha kinyitsz egy dobozt, és kiveszed a különféle tárgyakat, például kábeleket, fejhallgatót vagy USB-t.

  11 Megbízható podcast 🎧 Tárhely kis- és nagyvállalkozások számára

A Pythonban való kicsomagolás hasonló a doboz kicsomagolásához a való életben.

>>> mybox = ['cables', 'headphones', 'USB']
>>> item1, item2, item3 = mybox

Fordítsuk le ugyanezt a példát kódra a jobb megértés érdekében:

Amint látja, a mybox listán belüli három elemet három változóhoz rendeljük hozzá: item1, item2, item2. Ez a fajta változó-hozzárendelés a kicsomagolás alapvető koncepciója a Pythonban.

>>> item1
'cables'
>>> item2
'headphones'
>>> item3
'USB'

Ha megpróbálja megszerezni az egyes tételek értékét, észre fogja venni, hogy az item1 a „kábelekre”, az item2 a „fejhallgatóra” és így tovább.

>>> newbox = ['cables', 'headphones', 'USB', 'mouse']
>>> item1, item2, item3 = newbox
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 3)

Eddig úgy tűnik, minden rendben van ezzel a kóddal, de mi lenne, ha egy listát akarnánk kicsomagolni több elemmel – megtartva ugyanannyi hozzárendelt változót?

Valószínűleg erre a hibára számított. Lényegében 4 listaelemet rendelünk három változóhoz, hogyan tudja a Python hozzárendelni a megfelelő értékeket? Nem, ez azért van, mert kapunk a ValueError

a „túl sok érték a kicsomagoláshoz” üzenettel. Ez azért történik, mert három változót állítunk be a bal oldalon, és négy értéket (amely a newbox listának felel meg) a jobb oldalon.

>>> lastbox = ['cables', 'headphones']
>>> item1, item2, item3 = lastbox
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 3, got 2)

Ha hasonló folyamatot próbál végrehajtani, de több változóval, mint értékkel kell kicsomagolni, egy másik ValueError üzenetet fog kapni, kivéve azt, amely egy kissé eltérő üzenettel:

Megjegyzés: Dolgoztunk már listákkal, de ezt a kicsomagolási formát bármilyen iterálható elemmel (listák, halmazok, sorok, szótárak) használhatja.

Tehát hogyan lépjük túl ezt a helyzetet? Van valami mód arra, hogy egy iterálható elem összes elemét kicsomagolja néhány változóra anélkül, hogy hiba lépne fel?

Persze van, és kicsomagolási operátornak vagy csillag operátornak (*, **) hívják. Lássuk, hogyan kell használni Pythonban.

Listák kicsomagolása a * operátorral

A csillag operátor

>>> first, *unused, last = [1, 2, 3, 5, 7]
>>> first
1
>>> last
7
>>> unused
[2, 3, 5]

Az iterálható összes érték kicsomagolására szolgál, amely még nincs hozzárendelve.

>>> first, *_, last = [1, 2, 3, 5, 7]
>>> _
[2, 3, 5]

Tegyük fel, hogy indexek használata nélkül szeretné megszerezni a lista első és utolsó elemét, ezt megtehetjük a csillag operátorral:

>>> first, *_, last = [1, 2]
>>> first
1
>>> last
2
>>> _
[]

Érthető, hogy az összes fel nem használt értéket a csillag operátorral kapjuk meg. Az értékek elvetésének előnyben részesített módja egy aláhúzás változó (_) használata, amelyet néha „álváltozóként” használnak.

  Mi az a Spotify Kids? (és hogyan kell használni a szülői felügyeletet)

Akkor is használhatjuk ezt a trükköt, ha a listának csak két eleme van:

Ebben az esetben az aláhúzás változó (dummy változó) egy üres listát tárol, így a körülöttük lévő másik két változó hozzáférhet a lista elérhető értékeihez.

>>> *string = 'PythonIsTheBest'

Általános hibaelhárítás

>>> *string = 'PythonIsTheBest'
  File "<stdin>", line 1
SyntaxError: starred assignment target must be in a list or tuple

Kicsomagolhatjuk egy iterálható egyedi elemét. Például valami ilyesmit találna ki: A fenti kód azonban SyntaxError-t ad vissza:Ez azért van, mert szerint a

PEP specifikáció

:

>>> *string, = 'PythonIsTheBest'
>>> string
['P', 'y', 't', 'h', 'o', 'n', 'I', 's', 'T', 'h', 'e', 'B', 'e', 's', 't']

Egy sor (vagy lista) egy egyszerű feladat bal oldalán

>>> *numbers, = range(5)
>>> numbers
[0, 1, 2, 3, 4]

Ha egy iterálhatóság összes értékét egyetlen változóba szeretnénk kicsomagolni, akkor be kell állítani egy tuple-t, így elég egy egyszerű vessző hozzáadása:

Egy másik példa a range függvény használata, amely számsort ad vissza.

Most, hogy tudja, hogyan kell kicsomagolni a listákat és a sorokat csillaggal, ideje belevágni a kicsomagoló szótárakba.

A szótárak kicsomagolása a ** operátorral

>>> **greetings, = {'hello': 'HELLO', 'bye':'BYE'} 
...
SyntaxError: invalid syntax

Míg a listák és sorok kicsomagolásához egyetlen csillagot használnak, a szótárak kicsomagolásához a kettős csillagot (**) használják.

>>> food = {'fish':3, 'meat':5, 'pasta':9} 
>>> colors = {'red': 'intensity', 'yellow':'happiness'}
>>> merged_dict = {**food, **colors}
>>> merged_dict
{'fish': 3, 'meat': 5, 'pasta': 9, 'red': 'intensity', 'yellow': 'happiness'}

Sajnos a szótárt nem tudjuk egyetlen változóra kicsomagolni, ahogyan azt a sorok és listák esetében tesszük. Ez azt jelenti, hogy a következő hibaüzenetet fog kiadni:

Használhatjuk azonban a ** operátort a hívható és egyéb szótárak belsejében. Például, ha más szótárakból összevont szótárt szeretnénk létrehozni, használhatjuk az alábbi kódot:

Ez egy meglehetősen rövid módja az összetett szótárak létrehozásának, azonban nem ez a fő módja a kicsomagolásnak Pythonban.

Lássuk, hogyan tudjuk használni a kicsomagolást hívható eszközökkel

Csomagolás funkciókban: args és kwargs

Valószínűleg láttál már args-t és kwarg-ot osztályokon vagy függvényeken implementálva. Nézzük meg, miért kell ezeket a hívható elemekkel együtt használnunk.

>>> def product(n1, n2):
...     return n1 * n2
... 
>>> numbers = [12, 1]
>>> product(*numbers)
12

Csomagolás a * operátorral (args)

>>> product(12, 1)
12

Tegyük fel, hogy van egy függvényünk, amely kiszámolja két szám szorzatát.

>>> numbers = [12, 1, 3, 4]
>>> product(*numbers)
...
TypeError: product() takes 2 positional arguments but 4 were given

Amint láthatja, a listaszámokat kicsomagoljuk a függvénybe, így valójában a következőt futtatjuk:

>>> def product(*args):
...     result = 1
...     for i in args:
...             result *= i
...     return result
...
>>> product(*numbers)
144

Eddig minden rendben működik, de mi van, ha egy hosszabb listát szeretnénk átadni? Ez minden bizonnyal hibát okoz, mert a függvény több argumentumot kap, mint amennyit képes kezelni.

  Fődokumentum létrehozása és aldokumentumok hozzáadása az MS Word 2016-ban

Mindezt úgy tudjuk megoldani, hogy a listát közvetlenül a függvényre pakoljuk, ami egy iterálhatót hoz létre a függvényen belül, és lehetővé teszi, hogy tetszőleges számú argumentumot adjunk át a függvénynek.

Itt az args paramétert iterálható elemként kezeljük, végigjárjuk az elemeit, és visszaadjuk az összes szám szorzatát. Figyeljük meg, hogy az eredmény kezdő számának egynek kell lennie, mert ha nullával kezdjük, a függvény mindig nullát ad vissza. Megjegyzés: az args csak egy megállapodás, bármilyen más paraméternevet használhatA függvénynek tetszőleges számokat is átadhatunk lista használata nélkül, akárcsak a beépítettnél

>>> product(5, 5, 5)
125
>>> print(5, 5, 5)
5 5 5

nyomtatási funkció

>>> def test_type(*args):
...     print(type(args))
...     print(args)
... 
>>> test_type(1, 2, 4, 'a string')
<class 'tuple'>
(1, 2, 4, 'a string')

.

Végül nézzük meg egy függvény arg-jainak objektumtípusát.

Ahogy a fenti kódban megjegyeztük, az args típusa mindig sor lesz, és a tartalma a függvénynek átadott összes nem kulcsszavas argumentum lesz.

Csomagolás a ** kezelővel (kwargs)

>>> def make_person(name, **kwargs):
...     result = name + ': '
...     for key, value in kwargs.items():
...             result += f'{key} = {value}, '
...     return result
... 
>>> make_person('Melissa', id=12112, location='london', net_worth=12000)
'Melissa: id = 12112, location = london, net_worth = 12000, '

Mint korábban láttuk, a ** operátort kizárólag szótárak esetén használjuk. Ez azt jelenti, hogy ezzel az operátorral kulcs-érték párokat tudunk átadni a függvénynek paraméterként.

Hozzuk létre a make_person függvényt, amely a „name” pozíció argumentumot és meghatározatlan mennyiségű kulcsszavas argumentumot kap.

Amint láthatja, a **kwargs utasítás az összes kulcsszavas argumentumot szótárba konvertálja, amelyet a függvényen belül ismételhetünk.

>>> def test_kwargs(**kwargs):
...     print(type(kwargs))
...     print(kwargs)
... 
>>> test_kwargs(random=12, parameters=21)
<class 'dict'>
{'random': 12, 'parameters': 21}

Megjegyzés: a kwargs csak egy konvenció, és ezt a paramétert tetszés szerint nevezheti el

A kwargok típusát ugyanúgy ellenőrizhetjük, mint az argoknál:

>>> def my_final_function(*args, **kwargs):
...     print('Type args: ', type(args))
...     print('args: ', args)
...     print('Type kwargs: ', type(kwargs))
...     print('kwargs: ', kwargs)
... 
>>> my_final_function('Python', 'The', 'Best', language="Python", users="A lot")
Type args:  <class 'tuple'>
args:  ('Python', 'The', 'Best')
Type kwargs:  <class 'dict'>
kwargs:  {'language': 'Python', 'users': 'A lot'}

A kwargs belső változó mindig szótárrá változik, amely a függvénynek átadott kulcs-érték párokat tárolja.

Végül használjuk az argokat és a kwargokat ugyanabban a függvényben:

Következtetés

  • A kicsomagoló operátorok nagyon hasznosak a mindennapi feladatokban, most már tudja, hogyan kell használni őket egyedi utasításokban és függvényparaméterekben is.
  • Ebben az oktatóanyagban a következőket tanultad:
  • A *-t a sorokhoz és a listákhoz, a **-ot pedig a szótárakhoz használja
  • Kicsomagoló operátorokat használhat függvény- és osztálykonstruktorokban

Az args nem kulcsszavas paramétereket ad át a függvényeknekA kwargokat kulcsszavas paraméterek átadására használják függvényeknek.