A Python programozási nyelvben van egy speciális szintaktikai konstrukció, amely lehetővé teszi bizonyos szabályok szerint kitöltött listák létrehozását. Az ilyen szerkezeteket ún listagenerátorok. Kényelmük a rövidebb jelölésben rejlik programkód mintha a lista a szokásos módon jönne létre.

Például létre kell hoznia egy listát természetes számokkal egy bizonyos számig. A "klasszikus" mód valahogy így nézne ki:

>>>a= >>> az i tartományban (1 , 15 ): ...a.hozzáfűzés(i) ... >>> a

A lista létrehozásához három sornyi kódra volt szükség. A generátor ezt egyben megteszi:

>>> a = [i az i-hez az (1, 15) tartományban] >>> a

Itt az építkezés [ i for i az (1 , 15 ) tartományban ] egy listagenerátor. Az egész konstrukció szögletes zárójelben van, ami mintegy azt mondja, hogy egy lista készül. A szögletes zárójelben három rész különíthető el: 1) mit csinálunk az elemmel (jelen esetben nem csinálunk semmit, csak felvesszük a listába), 2) mit veszünk (jelen esetben az i elemet) , 3) honnan vesszük (itt a tartomány objektumból) . Az alkatrészeket kulcsszavak választják el egymástól számáraés ban ben.

Tekintsük ezt a példát:

>>> a = [ 2 , -2 , 4 , -4 , 7 , 5 ] >>> b = [i**2 az i-hez az a-ban] >>>b

Ebben az esetben a listagenerátor minden elemet kivesz az a listából, és négyzetre emeli. Így 1) amit csinálunk - négyzetre emeljük az elemet, 2) amit veszünk - az elemet, 3) hová vesszük - az a listából.

>>> >>> b = [ i*a[ i] for i in a] >>>b

Itt a kulcsot a szótárból veszik, és a kulcs és annak értékének szorzata hozzáadódik a generált listához.

>>> a = ( 1:10 , 2:20 , 3:30 ) >>> b = [ [ i, a[ i] ] for i in a] >>>b [, , ] >>> c = [ j i-re b-ben j-re i-ben] >>> c

Ebben a példában a generált b lista beágyazott listákból áll. Ha a generátor kihagyta volna a szögletes zárójeleket a kifejezésből [én, a[i]], akkor hiba történne. Ha továbbra is meg kell szereznie a szótár kulcsainak és értékeinek egyszintű listáját, akkor minden beágyazott listát ki kell vennie, és ki kell vennie az egyes elemeket. Ezt a beágyazott szerkezettel érik el számára, amely a c sorban látható = [j i-re b-ben j-re i-ben]. A c lista feltöltésének „klasszikus” szintaxisa így néz ki:

>>>c= >>> a b-ben: ... j-re az i-ben: ...c.hozzáfűzés(j) ... >>> c

A generátor végén hozzáadhatja a szerkezetet ha. Például az összes számjegyet ki kell bontani egy karakterláncból :) if i%30 == 0 vagy i%31 == 0 ] >>> a

Így a generátorok egyszerűbbé és gyorsabbá teszik a listák létrehozását. Ezek azonban nem helyettesíthetik a meglehetősen bonyolult szerkezeteket. Például amikor az érvényesítési feltételnek tartalmaznia kell az ágat más.

A Pyrhon programozási nyelvnek van egy speciális szintaxisa, amely lehetővé teszi bizonyos szabályok alapján kitöltött listák létrehozását. A generált listák eltérőek lehetnek, a struktúra tartalma eltérő lehet, ezért ezeket listagenerátoroknak nevezzük. Kényelmesek, mert a bejegyzések nem olyan hosszúak, mint a hagyományos listakészítési módszerrel.

Például szüksége van egy természetes számok listájára egy adott számig. hagyományos módszerígy fog kinézni:

>>> a = >>> i-re in range(1,15): ... a.append(i) ... >>>

A lista három sornyi kódot tartalmazott. És a generátornak csak egy kell:

>>> a = >>> a

A konstrukció egy listagenerátor. Minden konstrukciót négyzetes listákba kell helyezni, ami tükrözi a lista létrehozását. A tartókon belül három rész található:

  1. Mit fogunk csinálni az elemekkel (a mi helyzetünkben nem csinálunk semmit, csak felvesszük a listára).
  2. Mit fogunk venni (i elemet veszünk).
  3. Honnan vesszük (a range objektumból). A részek szétválasztásához használja az in és for kulcsszavakat.

Nézzünk egy példát

>>> a = >>> b = >>> b

Ebben a helyzetben a lista minden elemét vesszük négyzetre. Innen:

  1. Megtesszük – elemünket négyzetre emeljük.
  2. Vegyünk egy elemet.
  3. From - a listából a.
>>> a = (1:10, 2:20, 3:30) >>> b = i-re az a-ban] >>> b

Itt vesszük a kulcsot a szótárban, és a kulcs szorzata és értéke bekerül a generált listába.

>>> a = (1:10, 2:20, 3:30) >>> b = [] for i in a] >>> b [, , ] >>> c = >>> c

Ebben az esetben a b lista beágyazott listákat tartalmaz. A szögletes zárójelek elhagyása a generátorban a ] kifejezésben hibát eredményez. Ha egyszintű listára van szüksége a szótári értékek kulcsaival, akkor minden beágyazott listát ki kell vennie, és onnan kell átvennie az egyes összetevőket. Ez egy beágyazott konstrukcióval történik. A hagyományos listázási szintaxis a következő:

>>> c = >>> i-re b-ben: ... j-re i-ben: ... c.append(j) ... >>> c

A lista megértése kiegészíthető egy if konstrukcióval. Például az összes számot ki kell bontania egy karakterláncból:

>>> a="lsj94ksd231 9" >>> b=

Vagy töltse ki a listát olyan számokkal, amelyek 31 vagy 30 többszörösei:

>>> a = >>> a

A listák létrehozása sokkal egyszerűbb és gyorsabb. De nem alkalmasak meglehetősen bonyolult szerkezetek helyettesítésére. Például, ha az ellenőrzési feltételben van egy else ág.

Elfogy a pénz, és még pár hét múlva fizetésnap? Lehet kölcsönkérni, de mi van, ha nincs senki? Ne menj a bankba kölcsönért. Ebben az esetben a mikrohitelek segítenek. Csak menjen az oldalra, töltsön ki egy jelentkezést (nagyon egyszerű és gyors), és néhány percen belül megkapja a pénzt! Nagyon kényelmes és gyors, és ami a legfontosabb, nem kell senkit megkérdezni!

A lista-megértések (listagenerátorok), furcsa módon, a listák kényelmes feldolgozására szolgálnak, amely magában foglalja új listák létrehozását és a meglévők módosítását.

Tegyük fel, hogy egy listát kell kapnunk a páratlan számokról, amelyek nem haladják meg a 25-öt. Elvileg az xrange parancs működésének megismerése után nem nehéz megoldani ezt a problémát.

Res = x-hez xrange(1, 25, 2): res.append(x) ... res nyomtatása

Általánosságban elmondható, hogy a kapott eredmény mindenben megfelel nekünk, kivéve a hosszú rekordot. Itt jön a "cukrunk" segítségére. A nagyon egyszerű alak, õ, álltalában

Res = ... nyomtatás res

A szintaxis alapvetően egyszerű. A teljes kifejezés szögletes zárójelben van. Először jön egy kifejezés, amely beállítja a lista elemeit, majd - egy ciklus, amellyel megváltoztathatja a kifejezést. Mindkét rész tetszőlegesen összetett lehet. Például így kaphat listát az azonos páratlan számok négyzeteiről.

Opcionálisan hozzáadhat további feltételek szűrés. Például módosítsuk az előző példánkat úgy, hogy a 3-mal osztható számok négyzetei ne legyenek kizárva.

Res = ... nyomtatás res

Feladat 6.1. Lista generátor

Listát kell szerezni bináris számok amelyek nem négyzetek.

Generátorok

Az olyan konstrukciók, mint a mylist = olyan elemek listája, amelyek értékei a memóriában vannak tárolva. Alkalmazhatja a for i-t a mylistben: print(i) konstruáljon rájuk, hogy annyiszor dolgozzon az elemekkel, ahányszor csak akarja.

A generátorok is iterálható objektumok, de csak egyszer olvashatók. Ennek az az oka, hogy nem tárolnak értékeket a memóriában, hanem menet közben generálják őket:

mygenerator = (x*x x esetén a(3) tartományban) i esetén a saját generátorban: print(i)

Minden ugyanaz, kivéve, hogy a négyzetek helyett zárójeleket használnak. DE: a for i-t nem lehet másodszor alkalmazni a mygenerator konstrukcióban, mivel a generátor csak egyszer használható: kiértékel 0-ra, majd elfelejti és 1-re értékel, végül 4-gyel fejezi be - egymás után. A len() -vel sem lehet lekérni az elemek számát. A generátorokat a mygenerator nem tudja szeletelni. A generátorok azonban lehetővé teszik a program futtatásához szükséges memória mennyiségének csökkentését.

Hozam

A hozam egy kulcsszó, amelyet a return kifejezéshez hasonlóan használnak – a különbség az, hogy a függvény egy generátort ad vissza.

Def createGenerator() : mylist = range(3) for i in mylist: hozam i*i mygenerator = createGenerator() # generátor létrehozása i számára a mygeneratorban: print(i)

Feladat 6.2. Tetraéder számgenerátor

A háromszögszámgenerátor segítségével hozzon létre egy tetraéderszámgenerátort.

Feladat 6.3. transzfúziós generátor

Van egy iskolai probléma a szükséges térfogat megszerzésével egy végtelen medence és két vödör használatával. Például: 4 litert kell beszereznie két 3 és 5 literes vödör használatával. Van rá megoldás a biliárdlabda módszerrel.

Létre kell hozni egy generátort, amely számpárokat állít elő - az edények teljességét. Munka példa:

Vödörek = pool(3,5) a,b-hez vödrökben: print("a=",a," b=",b) if b==4: break

Ma egy olyan adattípusról fogok beszélni, mint listákon, ezek műveletei és módszerei, a listaértések és a listák használata.

Mik azok a listák?

A Python listái tetszőleges típusú objektumok rendezett, változtatható gyűjteményei (hasonlóan egy tömbhöz, de a típusok eltérőek lehetnek).

A listák használatához létre kell hozni azokat. A lista létrehozásának többféle módja van. Például bármilyen iterálható objektumot (például ) feldolgozhat a beépített funkcióval lista:

>>> lista("lista") ["lista"]

Lista egy literál használatával is létrehozható:

>>> s = # Üres lista >>> l = [ "s" , "p" , [ "isok" ], 2 ] >>> s >>> l ["s", "p", ["isok" "], 2]

Amint a példából látható, egy lista tetszőleges számú objektumot tartalmazhat (beleértve a beágyazott listákat is), vagy nem tartalmazhat semmit.

És egy másik módja a lista létrehozásának listagenerátorok. A listaértelmezés egy módja annak, hogy új listát készítsünk úgy, hogy egy kifejezést alkalmazunk a sorozat minden elemére. A listaértelmezések nagyon hasonlítanak a hurokhoz.

>>> c = [ c * 3 c-hez a "listában" ] >>> c ["lll", "iii", "sss", "ttt"]

A listagenerátor bonyolultabb felépítése is lehetséges:

>>> c = [ c * 3 c a "listában", ha c != "i" ] >>> c ["lll", "sss", "ttt"] >>> c = [ c + d for c a "listában", ha c != "i" d a "spam"-ben, ha d != "a" ] >>> c ["ls", "lp", "lm", "ss", "sp", "sm", "ts", "tp", "tm"]

Bonyolult esetekben azonban jobb egy szabályos for ciklust használni a listák létrehozásához.

Funkciók és módszerek listája

Létrehozva létrehozva, most tennie kell valamit a listával. A listákhoz alapvető és listás módszerek állnak rendelkezésre.

Lista módszerek táblázat

MódszerMit csinál
list.append(x)Hozzáad egy elemet a lista végéhez
list.kiterjesztés(L)Kibővíti a listalistát az L lista összes elemének a végéhez fűzésével.
list.insert(i, x)Az x értéket beszúrja az i-edik elembe
list.remove(x)Eltávolítja a lista első elemét, amelynek x értéke van. ValueError, ha nem létezik ilyen elem
list.pop([én])Eltávolítja az i-edik elemet, és visszaadja. Ha nincs megadva index, akkor az utolsó elem eltávolításra kerül.
list.index(x,])Az első x értékű elem pozícióját adja vissza (keresés az elejétől a végéig)
list.count(x)Az x értékű elemek számát adja vissza
list.sort() Egy jellemző alapján rendezi a listát
lista.fordítva() Kibővíti a listát
list.másolat() A lista sekély másolata
lista.tiszta() Törli a listát

Meg kell jegyezni, hogy a lista metódusok a -val ellentétben magát a listát változtatják meg, ezért a végrehajtás eredményét nem kell ebbe a változóba írni.

>>> l = [ 1 , 2 , 3 , 5 , 7 ] >>> l . sort() >>> l >>> l = l . sort() >>> print(l) Nincs

És végül, példák a listákkal való munkára:

>>> a = [ 66.25 , 333 , 333 , 1 , 1234.5 ] >>> print (a . count (333 ), a . count (66.25 ), a . count ("x")) 2 1 0 >>> a. beszúrni (2 , - 1 ) >>> a . append(333) >>> a >>> a. index (333 ) 1 >>> a . eltávolítás(333) >>> a >>> a. fordított() >>> a >>> a. sort() >>> a [-1, 1, 66.25, 333, 333, 1234.5]

Időnként a teljesítmény növelése érdekében a listákat sokkal kevésbé rugalmasakra cserélik.

A generátorok és iterátorok olyan eszközök, amelyeket általában adatfolyamok továbbítására használnak. A leckében megvizsgáljuk az iterátorok fogalmát Piton, tanulja meg saját iterátorok létrehozását, és rájön, hogyan kell dolgozni generátorokkal.

Iterátorok Pythonban

Sokban modern nyelvek a programozás ilyen entitásokat használ iterátorként. Fő céljuk, hogy egyszerűsítsék a navigációt egy objektum elemei között, amely általában egy gyűjtemény (lista, szótár stb.). Nyelv Piton, ebben az esetben sem kivétel, és támogatja az iterátorokat is. Az iterátor egy enumerator objektum, amely egy adott objektum esetén ad vissza következő elem, vagy kivételt dob, ha nincs több elem.

Az iterátorok használatának fő helye a ciklusban van. számára. Ha valamilyen lista elemei vagy egy karakterlánc karakterei felett iterálsz egy hurokkal számára, akkor ez tulajdonképpen azt jelenti, hogy a ciklus minden iterációjával a string / listában lévő iterátor elérése a következő elem visszaadásának követelményével történik, ha nincs több elem az objektumban, akkor az iterátor dob a cikluson belül feldolgozott kivétel számára láthatatlan a felhasználó számára.

Íme néhány példa, amelyek segítenek jobban megérteni ezt a fogalmat.Először is jelenítsük meg egy tetszőleges lista elemeit a képernyőn.

> > > szám_lista => > > i-hez a szám_listában: nyomtatás (i) 1 2 3 4 5

Mint már említettük, olyan objektumok, amelyek elemei ciklusban iterálhatók számára, iterátor objektumot tartalmaznak, ennek beszerzéséhez a függvényt kell használni iter(), és a következő elem kinyeréséhez az iterátorból - a függvény következő().

> > > itr = iter (num_list) > > > print (next(itr)) 1 > > > print (next(itr)) 2 > > > print (next(itr)) 3 > > > print (next(itr) )) 4 > > > print (next(itr)) 5 > > > print (next(itr)) Traceback (legutóbbi hívás utolsó): Fájl " ", 1. sor, be< module>print (next(itr)) StopIteration

Amint a fenti példából látható, a függvényhívás következő (itr) minden alkalommal a következő elemet adja vissza a listából, és amikor ezek az elemek elfogynak, kivételt dob ​​a rendszer StopIteration.

Saját iterátorok létrehozása

Ha a saját osztályának objektumán belül elemeket kell iterálnia, saját iterátort kell készítenie. Alkossunkosztály, amelynek objektuma egy iterátor lesz, amely bizonyos számú egységet állít elő, amelyet a felhasználó az objektum létrehozásakor ad meg. Egy ilyen osztály tartalmaz egy konstruktort, amely az egységek számát veszi be bemenetként, és egy metódust __következő__(), enélkül az osztály példányai nem lesznek iterátorok.

__benne__ < self .limit: self .counter += 1 return 1 else : raise StopIteration s_iter1 = SimpleIterator(3 ) print (next(s_iter1)) print (next(s_iter1)) print (next(s_iter1)) print (next(s_iter1))

Példánkban a negyedik függvényhíváson következő() kivételt dobnak StopIteration. Ha egy adott tárggyal egy hurokban akarunk dolgozni számára, majd az osztályba SimpleIterator módszert kell hozzáadni __iter__(), amely egy iterátort ad vissza, ebben az esetben ennek a metódusnak kell visszatérnie maga.

osztály SimpleIterator : def __iter__(self): return self def __benne__(self , limit ): self .limit = limit self .counter = 0 def __next__ (self ): if self .counter< self .limit: self .counter += 1 return 1 else : raise StopIteration s_iter2 = SimpleIterator(5 ) for i in s_iter2: print (i)

Generátorok

A generátorok sokkal könnyebbé teszik az iterátor felépítését. Az előző példákban egy iterátor felépítéséhez és munkához külön osztályt hoztunk létre. A generátor egy függvény, amely függvényben meghívva következő() visszaadja a következő objektumot a munka algoritmusa szerint. Ahelyett kulcsszó Visszatérés generátorban használják hozam. A generátor működését a legegyszerűbben egy példán keresztül láthatja. Írjunk egy függvényt, amely előállítja a szükséges egységek számát.

def egyszerű_generátor (val ): while val > 0 : val -= 1 hozam 1 gen_iter = egyszerű_generátor(5 ) print (next(gen_iter)) print (next(gen_iter)) print (next(gen_iter)) print (next(gen_iter) ) print (next(gen_iter)) print (next(gen_iter))

Ez a függvény pontosan úgy fog működni, mint az osztály SimpleIterator az előző példából.

A generátorok működésének megértésének kulcsa az, hogy amikor hív hozam a függvény nem hagyja abba a működését, hanem „lefagy” a függvény által elindított következő iterációig következő(). Ha a generátorban van, használja valahol a kulcsszót