V programovacím jazyce Python existuje speciální syntaktická konstrukce, která umožňuje vytvářet vyplněné seznamy podle určitých pravidel. Takové struktury se nazývají generátory seznamů. Jejich pohodlí spočívá v kratší notaci programový kód než kdyby byl seznam vytvořen běžným způsobem.

Například potřebujete vytvořit seznam naplněný přirozenými čísly do určitého čísla. "Klasický" způsob by vypadal asi takto:

>>>a= >>> pro i v rozsahu (1, 15): ...a.append(i) ... >>> a

Vytvoření seznamu trvalo tři řádky kódu. Generátor to udělá v jednom:

>>> a = [ i pro i v rozsahu (1, 15) ] >>> a

Zde konstrukce [i pro i v rozsahu (1, 15)] je generátor seznamů. Celá konstrukce je uzavřena v hranatých závorkách, což jakoby říká, že bude vytvořen seznam. Uvnitř hranatých závorek lze rozlišit tři části: 1) co s prvkem děláme (v tomto případě neděláme nic, jen jej přidáme do seznamu), 2) co bereme (v tomto případě prvek i) , 3) odkud to bereme (zde z objektu range) . Části jsou od sebe odděleny klíčovými slovy pro a v.

Zvažte tento příklad:

>>> a = [ 2 , -2 , 4 , -4 , 7 , 5 ] >>> b = [i**2 pro i v a] >>>b

V tomto případě generátor seznamu vezme každý prvek ze seznamu a a umocní jej na druhou. Tedy 1) co děláme - prvek odmocníme, 2) co bereme - prvek, 3) kde bereme - ze seznamu a .

>>> >>> b = [ i*a[ i] pro i v a] >>>b

Zde se klíč převezme ze slovníku a do vygenerovaného seznamu se přidá součin klíče a jeho hodnota.

>>> a = ( 1:10 , 2:20 , 3:30 ) >>> b = [ [ i, a[ i] ] pro i v a] >>>b [, , ] >>> c = [ j pro i v b pro j v i] >>> c

V tomto příkladu se vygenerovaný seznam b skládá z vnořených seznamů. Kdyby generátor ve výrazu vynechal hranaté závorky [i,a[i]], pak by došlo k chybě. Pokud stále potřebujete získat jednoúrovňový seznam klíčů a hodnot slovníku, musíte vzít každý vnořený seznam a vzít z něj každý prvek. Toho je dosaženo prostřednictvím vnořené konstrukce pro, který je znázorněn na řádku c = [j pro i v b pro j v i]. "Klasická" syntaxe pro naplnění seznamu c by vypadala takto:

>>>c= >>> pro i v b: ... pro j v i: ...c.append(j) ... >>> c

Na konec generátoru můžete přidat konstrukci -li. Například potřebujete extrahovat všechny číslice z řetězce :) if i%30 == 0 nebo i%31 == 0 ] >>> a

Generátory tak usnadňují a urychlují vytváření seznamů. Nemohou však nahradit poměrně složité struktury. Například když by podmínka ověření měla zahrnovat větev jiný.

Programovací jazyk Pyrhon má speciální syntaxi, která umožňuje vytvářet vyplněné seznamy na základě určitých pravidel. Generované seznamy mohou být různé, obsah struktury může být různý, proto se jim říká generátory seznamů. Jsou pohodlné, protože položky nejsou tak dlouhé jako u tradičního způsobu vytváření seznamů.

Potřebujete například seznam přirozených čísel až do konkrétního čísla. tradiční metoda bude vypadat takto:

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

Seznam obsahoval tři řádky kódu. A generátor potřebuje pouze jeden:

>>> a = >>> a

Konstrukce je generátor seznamu. Všechny konstrukce musí být umístěny ve čtvercových seznamech, což odráží vytvoření seznamu. Uvnitř závorek jsou tři části:

  1. Co uděláme s prvky (v naší situaci neděláme nic, jen je přidáme do seznamu).
  2. Co vezmeme (vezmeme prvek i).
  3. Odkud to vezmeme (z objektu range). K oddělení částí použijte klíčová slova in a for.

Podívejme se na příklad

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

V této situaci vezmeme každý prvek seznamu a umocníme jej. Odtud:

  1. Děláme - pozvedáme náš prvek do čtverce.
  2. Vezmeme prvek.
  3. Od - ze seznamu a.
>>> a = (1:10, 2:20, 3:30) >>> b = pro i v a] >>> b

Zde vezmeme klíč ve slovníku a součin klíče a jeho hodnoty se dostane do vygenerovaného seznamu.

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

V tomto případě seznam b obsahuje vnořené seznamy. Vynechání hranatých závorek v generátoru ve výrazu ] by vedlo k chybě. Pokud potřebujete jednoúrovňový seznam s klíči z hodnot slovníku, musíte vzít každý vnořený seznam a vzít odtud každou komponentu. To se provádí pomocí vnořené konstrukce for. Tradiční syntaxe výpisu je:

>>> c = >>> pro i v b: ... pro j v i: ... c.append(j) ... >>> c

Porozumění seznamu lze doplnit konstrukcí if. Například potřebujete extrahovat všechna čísla z řetězce:

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

Nebo vyplňte seznam čísly, která jsou násobky 31 nebo 30:

>>> a = >>> a

Seznamy se vytvářejí mnohem snadněji a rychleji. Nejsou však vhodné k nahrazení poměrně složitých struktur. Například pokud je v kontrolní podmínce větev else.

Došly peníze a do výplaty zbývá ještě pár týdnů? Půjčit si můžete, ale co když nikdo není? Nechoďte do banky pro půjčku. V tomto případě vám pomohou mikropůjčky. Stačí přejít na stránku, vyplnit žádost (je to velmi jednoduché a rychlé) a za pár minut obdržíte peníze! Velmi pohodlné a rychlé a hlavně se nemusíte nikoho ptát!

Přehledy seznamů (generátory seznamů) jsou kupodivu určeny pro pohodlné zpracování seznamů, které zahrnuje jak vytváření nových seznamů, tak i úpravy stávajících.

Řekněme, že potřebujeme získat seznam lichých čísel nepřesahujících 25. V zásadě není obtížné tento problém vyřešit jen seznámením se s prací příkazu xrange.

Res = for x in xrange(1, 25, 2): res.append(x) ... print res

Obecně platí, že získaný výsledek nám zcela vyhovuje se vším, s výjimkou dlouhého záznamu. Tady přijde na pomoc náš „cukr“. Ve velmi jednoduchá forma, on obvykle

Rozlišení = ... rozlišení tisku

Syntaxe je v zásadě jednoduchá. Celý výraz je psán v hranatých závorkách. Nejprve přichází výraz, který nastaví prvky seznamu, pak - smyčka, pomocí které můžete výraz změnit. Obě části mohou být libovolně složité. Zde je například návod, jak můžete získat seznam čtverců stejných lichých čísel.

Volitelně můžete přidat dodatečné podmínky filtrace. Upravme například náš předchozí příklad tak, aby byly vyloučeny druhé mocniny čísel dělitelných 3.

Rozlišení = ... rozlišení tisku

Úkol 6.1. Generátor seznamu

Je třeba získat seznam binární čísla které nejsou čtverce.

Generátory

Konstruuje jako mylist = tvoří seznamy prvků, jejichž hodnoty jsou uloženy v paměti. Můžete na ně použít konstrukci for i v mylist: print(i) a pracovat s prvky tolikrát, kolikrát chcete.

Generátory jsou také iterovatelné objekty, ale lze je číst pouze jednou. Je to proto, že neukládají hodnoty do paměti, ale generují je za běhu:

mygenerator = (x*x pro x v rozsahu(3)) pro i v mygenerator: print(i)

Vše je stejné, až na to, že místo hranatých jsou použity závorky. ALE: nemůžete použít for i v konstrukci mygenerator podruhé, protože generátor lze použít pouze jednou: vyhodnotí se na 0, pak na to zapomene a vyhodnotí se na 1, končící 4 - jeden po druhém. Také nemůžete získat počet prvků pomocí len() . Generátory nelze pomocí mygenerator rozdělit na plátky. Ale generátory vám umožňují snížit množství paměti pro spuštění programu.

Výtěžek

Yield je klíčové slovo, které se používá podobně jako return – rozdíl je v tom, že funkce vrátí generátor.

Def createGenerator() : mylist = range(3) for i in mylist: yield i*i mygenerator = createGenerator() # vytvoření generátoru pro i v mygenerator: print(i)

Úkol 6.2. Generátor čtyřstěnných čísel

Pomocí generátoru trojúhelníkových čísel vytvořte čtyřstěnný generátor čísel.

Úkol 6.3. generátor transfuze

Existuje školní problém se získáním požadovaného objemu pomocí nekonečného bazénu a dvou kbelíků. Například: potřebujete získat 4 litry pomocí dvou kbelíků o objemu 3 a 5 litrů. Existuje na to řešení metodou kulečníkové koule.

Je nutné vytvořit generátor, který produkuje dvojice čísel - plnost nádob. Příklad práce:

Buckets = pool(3,5) for a,b in buckets: print("a=",a," b=",b) if b==4: break

Dnes budu mluvit o takovém datovém typu, jako je seznamy, jejich operace a metody, pochopení seznamů a použití seznamů.

Co jsou seznamy?

Seznamy v Pythonu jsou uspořádané proměnlivé kolekce objektů libovolných typů (podobně jako pole, ale typy se mohou lišit).

Chcete-li používat seznamy, musíte je vytvořit. Existuje několik způsobů, jak vytvořit seznam. Pomocí vestavěné funkce můžete například zpracovat jakýkoli iterovatelný objekt (například ). seznam:

>>> seznam("seznam") ["seznam"]

Seznam lze také vytvořit pomocí literálu:

>>> s = # Prázdný seznam >>> l = [ "s" , "p" , [ "isok" ], 2 ] >>> s >>> l ["s", "p", ["isok "], 2]

Jak je vidět z příkladu, seznam může obsahovat libovolný počet libovolných objektů (včetně vnořených seznamů), nebo nemůže obsahovat nic.

A další způsob, jak vytvořit seznam, je generátory seznamů. Porozumění seznamu je způsob, jak vytvořit nový seznam použitím výrazu na každý prvek sekvence. Porozumění seznamu je velmi podobné smyčce.

>>> c = [ c * 3 pro c v "seznamu" ] >>> c ["lll", "iii", "sss", "tttt"]

Je také možná složitější konstrukce generátoru seznamu:

>>> c = [ c * 3 pro c v "seznamu", pokud c != "i" ] >>> c ["lll", "sss", "ttt"] >>> c = [ c + d pro c v "seznamu", pokud c != "i" pro d v "spam", pokud d != "a" ] >>> c ["ls", "lp", "lm", "ss", "sp", "sm", "ts", "tp", "tm"]

Ale ve složitých případech je lepší použít pro generování seznamů běžnou smyčku for.

Seznam funkcí a metod

Vytvořte vytvořeno, nyní musíte se seznamem něco udělat. Pro seznamy jsou k dispozici základní a seznamové metody.

Seznam metod tabulky

MetodaCo dělá
seznam.připojit(X)Přidá prvek na konec seznamu
seznam.prodloužit(L)Rozšiřuje seznam seznamu připojením všech prvků seznamu L na konec.
seznam.vložit(i, x)Vloží hodnotu x na i-tý prvek
seznam.odebrat(X)Odebere první prvek v seznamu, který má hodnotu x. ValueError, pokud žádný takový prvek neexistuje
seznam.pop([i])Odebere i-tý prvek a vrátí jej. Pokud není zadán žádný index, odstraní se poslední prvek.
seznam.index(X,])Vrátí pozici prvního prvku s hodnotou x (hledání od začátku do konce)
seznam.počet(X)Vrátí počet prvků s hodnotou x
seznam.seřadit() Seřadí seznam na základě funkce
seznam.reverzní() Rozšiřuje seznam
seznam.kopírovat() Mělká kopie seznamu
seznam.jasný() Vymaže seznam

Je třeba poznamenat, že seznamové metody na rozdíl od , mění samotný seznam, a proto není nutné výsledek provádění zapisovat do této proměnné.

>>> l = [ 1 , 2 , 3 , 5 , 7 ] >>> l . sort() >>> l >>> l = l . sort() >>> print(l) Žádný

A nakonec příklady práce se seznamy:

>>> a = [ 66,25 , 333 , 333 , 1 , 1234,5 ] >>> tisk (a . počet (333 ), a . počet (66,25 ), a . počet ("x")) 2 1 0 >>> A. vložka (2 , - 1 ) >>> a . append(333) >>> a >>> a . index (333 ) 1 >>> a . odstranit(333) >>> a >>> a . obrátit () >>> a >>> a . sort() >>> a [-1, 1, 66.25, 333, 333, 1234.5]

Pro zvýšení výkonu jsou seznamy občas nahrazeny mnohem méně flexibilními.

Generátory a iterátory jsou nástroje, které se obvykle používají pro streamování dat. V lekci se podíváme na koncept iterátorů v Krajta, naučte se vytvářet vlastní iterátory a zjistěte, jak pracovat s generátory.

Iterátory v Pythonu

V mnoha moderní jazyky programování používá takové entity jako iterátory. Jejich hlavním účelem je zjednodušit navigaci mezi prvky objektu, kterým je zpravidla kolekce (seznam, slovník atd.). Jazyk Krajta, v tomto případě není výjimkou a má také podporu pro iterátory. Iterátor je objekt enumerátoru, který se pro daný objekt vrací další prvek, nebo vyvolá výjimku, pokud nejsou žádné další prvky.

Hlavní místo pro použití iterátorů je ve smyčce. pro. Pokud iterujete přes prvky v některém seznamu nebo znaky v řetězci se smyčkou pro, pak to ve skutečnosti znamená, že s každou iterací cyklu se přistupuje k iterátoru obsaženému v řetězci / seznamu s požadavkem vrátit další prvek, pokud v objektu nejsou žádné další prvky, pak iterátor vyhodí výjimka zpracovaná v rámci smyčky pro pro uživatele neviditelné.

Zde je několik příkladů, které vám pomohou lépe porozumět tomuto konceptu.Nejprve si na obrazovce zobrazme prvky libovolného seznamu.

> > > num_list => > > pro i v num_list: tisknout (i) 1 2 3 4 5

Jak již bylo zmíněno, objekty, jejichž prvky lze iterovat ve smyčce pro, obsahuje objekt iterátoru, k jeho získání je třeba použít funkci iter() a extrahovat další prvek z iterátoru - funkci další().

> > > 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 (poslední poslední hovor): Soubor " ", řádek 1, in< module>print (next(itr)) StopIteration

Jak můžete vidět z příkladu výše, volání funkce další (itr) pokaždé vrátí další prvek ze seznamu, a když tyto prvky dojdou, vyvolá se výjimka StopIteration.

Vytváření vlastních iterátorů

Pokud potřebujete iterovat prvky v rámci objektu vlastní třídy, musíte si vytvořit svůj vlastní iterátor. Pojďme tvořittřída, jejímž objektem bude iterátor produkující určitý počet jednotek, který uživatel zadá při vytváření objektu. Taková třída bude obsahovat konstruktor, který vezme počet jednotek jako vstup a metodu __další__(), bez něj nebudou instance této třídy iterátory.

__init__ < 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))

V našem příkladu na čtvrtém volání funkce další() bude vyvolána výjimka StopIteration. Pokud chceme umět pracovat s daným objektem ve smyčce pro, pak do třídy SimpleIterator je třeba přidat metodu __iter__(), který vrací iterátor, v tomto případě by se tato metoda měla vrátit .

třída SimpleIterator : def __iter__(self ): návrat self def __init__(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átory

Generátory značně usnadňují konstrukci iterátorů. V předchozích příkladech jsme pro sestavení a práci s iterátorem vytvořili samostatnou třídu. Generátor je funkce, která, když je volána ve funkci další() vrátí další objekt podle algoritmu jeho práce. Namísto klíčové slovo vrátit se používané v generátoru výtěžek. Nejjednodušší způsob, jak zjistit, jak generátor funguje, je na příkladu. Napišme funkci, která vygeneruje počet jednotek, které potřebujeme.

def simple_generator (val ): while val > 0 : val -= 1 výnos 1 gen_iter = simple_generator(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))

Tato funkce bude fungovat přesně jako třída SimpleIterator z předchozího příkladu.

Klíčem k pochopení toho, jak generátory fungují, je to, když zavoláte výtěžek funkce nezastaví svou práci, ale je „zmrazena“ až do další iterace spuštěné funkcí další(). Pokud jste ve svém generátoru, použijte někde klíčové slovo