From 765a174db3b4747261567a2e5a7b047a65588ae7 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 1 Apr 2019 15:55:16 +0200 Subject: [PATCH 01/17] Reword Lists & Tuples, add a graphic on mutation methods, add links --- lessons/beginners/list/index.md | 353 +++--- lessons/beginners/list/static/methods.svg | 1178 +++++++++++++++++++++ lessons/beginners/tuple/index.md | 42 +- 3 files changed, 1358 insertions(+), 215 deletions(-) create mode 100644 lessons/beginners/list/static/methods.svg diff --git a/lessons/beginners/list/index.md b/lessons/beginners/list/index.md index f51b69c8a2..9e16a9a363 100644 --- a/lessons/beginners/list/index.md +++ b/lessons/beginners/list/index.md @@ -1,27 +1,15 @@ -Tahle kapitola je plná nových věcí. -Doufám, že vydržíš až do konce. A kdyby něco -zatím nedávalo úplně smysl, nevěš hlavu: -věci, které si teď vysvětlíme, se opravdu naučíš -až v dalších lekcích, kde je budeme využívat -prakticky. - Encyklopedické informace z této stránky shrnuje [Tahák na seznamy](https://github.com/pyvec/cheatsheets/blob/master/lists/lists-cs.pdf), -který si doporučuji vytisknout. - -Každý příklad v tomto textu si vyzkoušej; -to, co Python vypíše, je důležitá součást lekce, -i když v materiálech není přímo napsaná. +který si můžeš vytisknout. # Seznamy Dnes si ukážeme, jak pracovat se *seznamy* (angl. *lists*). -Doufám, že víš, kde máš na klávesnici hranaté -závorky, protože právě těmi se seznamy vytváří: +Zapisují se hranatými závorkami: ```python -cisla = [1, 1, 2, 3, 5, 8, 13] -print(cisla) +zviratka = ['pes', 'kočka', 'králík'] +print(zviratka) ``` > [note] @@ -30,14 +18,14 @@ print(cisla) Seznam je hodnota, která může obsahovat spoustu dalších hodnot. Tak jako řetězec obsahuje sekvenci znaků, -seznam obsahuje sekvenci... čehokoliv. Třeba čísel. +seznam obsahuje sekvenci... čehokoliv. Třeba slov (řetězců). A tak jako můžeme pomocí cyklu `for` procházet řetězec po znacích, seznam můžeme procházet po jednotlivých prvcích: ```python -for cislo in cisla: - print(cislo) +for zviratko in zviratka: + print(zviratko) ``` Seznamy se v programech vyskytují velice často: @@ -49,74 +37,89 @@ matematika je plná číselných řad, každá online služba má seznam uživatelů. -Hodnoty v seznamu můžou být jakéhokoli typu, -dokonce můžeme různé typy míchat v jednom seznamu +Hodnoty v seznamu můžou být jakéhokoli typu. +Dokonce můžeme různé typy míchat v jednom seznamu (i když s takovými namixovanými seznamy se -příliš často nesetkáme – více se používají v -n-ticích, o kterých si povíme později): +příliš často nesetkáme – více se různé typy hodnot +používají v n-ticích, o kterých si povíme později): ```python seznam = [1, 'abc', True, None, range(10), len] print(seznam) ``` -## Vybírání ze seznamů +## Neměnitelné hodnoty + +Důležitá vlastnost seznamů je, že se dají *měnit*. -Nejzákladnější operaci se seznamy, -cyklus `for`, už jsme si ukázal{{gnd('i', 'y', both='i')}}. -Druhá nejdůležitější operace je vybírání -jednotlivých prvků. -To funguje jako u řetězců: do hranatých závorek -se dá číslo prvku. Čísluje se, jako u řetězců, -od nuly; záporná čísla označují prvky od konce. +Než vysvětlíme o co jde, připomeňme si jak fungují hodnoty, které se měnit +nedají – např. čísla, řetězce, `True`/`False`/`None`. + +Vyzkoušej si následující kousek kódu. Co je na něm „špatně“? ```python -print(cisla[2]) +kamaradka = 'Žaneta' +print(kamaradka) +kamaradka.upper() +print(kamaradka) ``` -Hranatými závorkami můžeme získávat podseznamy. -[Diagram z materiálů k řetězcům]({{ lesson_url('beginners/str')}}#slicing-diagram) -ukazuje, jak u takového „sekání” číslovat: -funguje to stejně, jen místo menšího řetězce -dostaneme menší seznam. +Proměnná `kamaradka` obsahuje řetězec `'Žaneta'` (který se už nedá změnit). +Metoda `upper()` vytvoří a vrátí *nový* řetězec. +Výsledná hodnota se ale v našem programu nevyužije – Python ji vypočítá, +ale pak na ni „zapomene“. + +Oprava je snadná: výsledek uložit do proměnné. +Často budeš chtít takový výsledek uložit do původní proměnné: ```python -print(cisla[2:-3]) +kamaradka = kamaradka.upper() ``` -## Měnění seznamů +Tímto přiřazením Python „zapomene“ na původní hodnotu, +a od tohoto příkazu dál bude proměnná `kamaradka` označovat nový řetězec. + +Podobně by se dala proměnná přenastavit na jakoukoli jinou hodnotu: + +```python +kamaradka = 'Žaneta' +print(kamaradka) +kamaradka = 'Alexandra' +print(kamaradka) +``` -Důležitá vlastnost seznamů, kterou nemají ani čísla, ani řetězce -(a `True`/`False`/`None` už vůbec ne), je, -že seznamy se dají měnit. -Čísla měnit nejdou – máš-li `a = 3` a -napíšeš `a = a + 1`, číslo `3` se nezmění. -Vypočítá se nové číslo `4` a proměnná `a` -se nastaví na toto nové číslo. +## Měnění seznamů + +A jak jsou na tom seznamy? +Ty se měnit dají. -Oproti tomu seznamy se dají měnit bez nastavování proměnné. Základní způsob, jak změnit seznam, je přidání prvku na konec pomocí metody `append`. -Ta *nic nevrací* (resp. vrací `None`), -ale „na místě” (angl. *in place*) změní +Ta *nic nevrací* (resp. vrací `None`), ale „na místě” (angl. *in place*) změní seznam, na kterém pracuje. Vyzkoušej si to: -```python -prvocisla = [2, 3, 5, 7, 11, 13, 17] -print(prvocisla) -prvocisla.append(19) -print(prvocisla) +```pycon +>>> zviratka = ['pes', 'kočka', 'králík'] +>>> print(zviratka) +['pes', 'kočka', 'králík'] +>>> zviratka.append('morče') +>>> print(zviratka) +['pes', 'kočka', 'králík', 'morče'] ``` -Takové měnění hodnoty může být občas překvapující, -protože stejnou hodnotu může mít více proměnných. +Všimni si, že proměnná `zviratka` se nastavuje jen na začátku. +V celém programu výše jen jeden seznam – na začátku má tři prvky, pak +mu jeden přibude, ale stále je to jeden a ten samý seznam. + +Takové měnění může být občas překvapující, +protože stejná hodnota může být přiřazená ve více proměnných. Protože se mění hodnota samotná, může to vypadat, -že se proměnná „mění aniž na ni sáhneme”: +že se „mění proměnná, aniž na ni sáhneme”: ```python -a = [1, 2, 3] # vytvoření seznamu -b = a # tady se nový seznam nevytváří +a = [1, 2, 3] # Vytvoření seznamu +b = a # Tady se nový seznam nevytváří! # seznam vytvořený v prvním řádku má teď dvě jména: "a" a "b", # ale stále pracujeme jenom s jedním seznamem @@ -128,101 +131,132 @@ print(b) ## Další způsoby, jak měnit seznamy -Kromě metody `append`, která přidává -jediný prvek, existuje metoda `extend`, -která umí přidávat prvků víc. -Prvky k přidání jí předáme ve formě seznamu: +Kromě metody `append`, která přidává jediný prvek na konec, existuje +spousta metod, které mění seznamy. +Všechny udělají přímo v daném seznamu, a (kromě `pop`) vrací `None`: + +* `extend()` přidá více prvků najednou, +* `insert()` přidá prvek na danou pozici, +* `pop()` odebere *a vrátí* poslední prvek, +* `remove()` odstraní první výskyt daného prvku, +* `sort()` seznam seřadí (řetězce “podle abecedy”, čísla vzestupně), +* `reverse()` obrátí pořadí prvků, +* `clear()` odstraní všechny prvky. + +{{ figure(img=static('methods.svg'), alt="Tahák") }} + +Například: ```python -dalsi_prvocisla = [23, 29, 31] -prvocisla.extend(dalsi_prvocisla) -print(prvocisla) +zviratka = ['pes', 'kočka', 'králík'] +zviratka.append('morče') # ['pes', 'kočka', 'králík', 'morče'] +zviratka.insert(2, 'had') # ['pes', 'kočka', 'had', 'králík', 'morče'] +zviratka.pop() # ['pes', 'kočka', 'had', 'králík'], vrátí 'morče' +zviratka.remove('had') # ['pes', 'kočka', 'králík'] +zviratka.sort() # ['kočka', 'králík', 'pes'] +zviratka.reverse() # ['pes', 'králík', 'kočka'] +zviratka.clear() # [] ``` -Metoda `extend` umí pracovat i s jinými -typy než se seznamy – ráda zpracuje cokoli, přes -co umí cyklit `for`: např. -jednotlivé znaky řetězců, řádky souborů, nebo čísla z `range()`. +## Vybírání ze seznamů + +Často budeš ze seznamu chtít vybrat prvek na určité pozici. +To funguje jako u řetězců: do hranatých závorek dáš číslo prvku. +Stejně jako u řetězců se čísluje od nuly a záporná čísla označují prvky +od konce. ```python -seznam = [] -seznam.extend('abcdef') -seznam.extend(range(10)) -print(seznam) +zviratka = ['pes', 'kočka', 'králík'] +print(zviratka[2]) ``` -## Měnění prvků +Hranatými závorkami můžeš získat i podseznam. +[Diagram z materiálů k řetězcům]({{ lesson_url('beginners/str')}}#slicing-diagram) +ukazuje, jak u takového „sekání” číslovat: +funguje to stejně, jen místo menšího řetězce +dostaneš menší seznam. + +```python +print(zviratka[2:-3]) +``` + +„Sekáním“ vzniká nový seznam – když pak ten původní změníš, v podseznamu se +to neprojeví. + -Ale dost přidávání. -Seznamům se dají i měnit jednotlivé prvky -a to jednoduše tak, že do prvku přiřadíme, -jako by to byla proměnná: +### Měnění prvků + +Na rozdíl od řetězců (které se nedají měnit) můžeš u existujících seznamů +nastavovat konkrétní prvky – a to tak, že do prvku přiřadíš jako by to byla +proměnná: ```python -cisla = [1, 0, 3, 4] -cisla[1] = 2 -print(cisla) +zviratka = ['pes', 'kočka', 'králík'] +zviratka[1] = 'koťátko' +print(zviratka) ``` Přiřazovat se dá i do podseznamu – v tomto případě se podseznam nahradí jednotlivými prvky z toho, -co přiřazujeme. -Jako u `extend` můžeš do podseznamu opět přiřadit cokoli, co umí -zpracovat `for` – seznam, řetězec, `range()` apod. +co přiřadíš. ```python -cisla = [1, 2, 3, 4] -cisla[1:-1] = [6, 5] -print(cisla) +zviratka = ['pes', 'kočka', 'králík', 'had', 'andulka'] +print([1:-1]) +zviratka[1:-1] = ['koťátko', 'králíček', 'hádě'] +print(zviratka) ``` -## Mazání prvků +### Mazání prvků Přiřazením do podseznamu se dá i změnit délka seznamu, nebo některé prvky úplně odstranit: ```python -cisla = [1, 2, 3, 4] -cisla[1:-1] = [0, 0, 0, 0, 0, 0] -print(cisla) +zviratka = ['pes', 'kočka', 'králík'] +zviratka[1:-1] = ['had', 'ještěrka', 'drak'] +print(zviratka) cisla[1:-1] = [] -print(cisla) +print(zviratka) ``` Tenhle zápis pro mazání prvků je ale docela -nepřehledný, a proto na to máme zvláštní příkaz -jménem `del`. +nepřehledný, a proto na to máme zvláštní příkaz jménem `del`. Jak už jeho název (z angl. *delete*, smazat) napovídá, smaže, co mu přijde pod ruku – jednotlivé prvky seznamů, podseznamy, … a dokonce i proměnné! ```python -cisla = [1, 2, 3, 4, 5, 6] -del cisla[-1] -print(cisla) -del cisla[3:5] -print(cisla) -del cisla -print(cisla) +zviratka = ['pes', 'kočka', 'králík', 'had', 'ještěrka', 'andulka'] + +print(zviratka[-1]) +del zviratka[-1] +print(zviratka) + +print(zviratka[1:-1]) +del zviratka[1:-1] +print(zviratka) + +del zviratka +print(zviratka) ``` -Další mazací metody jsou: -* `pop`, která odstraní *a vrátí* poslední prvek v seznamu – například pokud - mám seznam karet v balíčku, jde takhle jednoduše „líznout” kartu, -* `remove`, která najde v seznamu daný prvek a odstraní ho, +Nebo můžeš použít mazací metody zmíněné výše: +* `pop`, která odstraní *a vrátí* poslední prvek v seznamu, +* `remove`, která najde v seznamu první výskyt daného prvku a odstraní ho, * `clear`, která vyprázdní celý seznam. ```python -cisla = [1, 2, 3, 'abc', 4, 5, 6, 12] -posledni = cisla.pop() -print(posledni) -print(cisla) +balicek = ['eso', 'sedma', 'svršek', 'sedma', 'král'] +liznuta_karta = karty.pop() +print(liznuta_karta) +print(balicek) -cisla.remove('abc') -print(cisla) +balicek.remove('sedma') +print(balicek) -cisla.clear() -print(cisla) +balicek.clear() +print(balicek) ``` ## Řazení @@ -370,8 +404,7 @@ print(balicek) Seznamy a řetězce jsou druhy „sekvencí”, takže snad nepřekvapí, že se dá různě převádět z jednoho typu na druhý. -Funkce `list` vytvoří z řetězce -seznam znaků. +Funkce `list` vytvoří z řetězce seznam znaků. Když chceme dostat seznam slov, použijeme na řetězci metodu `split` (angl. *rozdělit*): @@ -383,17 +416,16 @@ print(slova) Metoda `split` umí brát i argument. Pokud ho předáme, místo mezer (a nových řádků) se řetězec „rozseká” daným oddělovačem. -Takže když máme nějaká data oddělená čárkami, -není nic jednoduššího než použít `split` s čárkou: +Takže když máš nějaká data oddělená čárkami, +použíj `split` s čárkou: ```python zaznamy = '3A,8B,2E,9D'.split(',') print(zaznamy) ``` -Chceme-li spojit seznam řetězců zase dohromady -do jediného řetězce, použijeme metodu -`join` (angl. *spojit*). +Chceš-li spojit seznam řetězců zase dohromady +do jediného řetězce, použij metodu `join` (angl. *spojit*). Pozor, tahle metoda se volá na *oddělovači*, tedy řetězci, kterým se jednotlivé kousky „slepí” dohromady; a jako argument bere seznam jednotlivých @@ -404,81 +436,6 @@ veta = ' '.join(slova) print(veta) ``` -## Úkol - -Představ si, že ti uživatelé zadávají jména a příjmení a ty si je ukládáš do -seznamu pro další použití např. v evidenci studentů. Ne všichni jsou ale pořádní, -a tak se v seznamu sem tam objeví i jméno s nesprávně zadanými velkými písmeny. -Například: - -```python -zaznamy = ['pepa novák', 'Jiří Sládek', 'Ivo navrátil', 'jan Poledník'] -``` - -Úkolem je: - -* Napsat funkci, která vybere jen ty správně zadané záznamy, které mají správně -jméno i příjmení s velkým počátečním písmenem. -* Napsat funkci, která vybere naopak jen ty nesprávně zadané záznamy. -* *(Nepovinný)* – Napsat funkci, která vrátí seznam s opravenými záznamy. - -Výsledné funkce by měly fungovat takto: - -```python -zaznamy = ['pepa novák', 'Jiří Sládek', 'Ivo navrátil', 'jan Poledník'] - -chybne_zaznamy = vyber_chybne(zaznamy) -print(chybne_zaznamy) # → ['pepa novák', 'Ivo navrátil', 'jan Poledník'] - -spravne_zaznamy = vyber_spravne(zaznamy) -print(spravne_zaznamy) # → ['Jiří Sládek'] - -opravene_zaznamy = oprav_zaznamy(zaznamy) -print(opravene_zaznamy) # → ['Pepa Novák', 'Jiří Sládek', 'Ivo Navrátil', 'Jan Poledník'] -``` - -> [note] -> Snadný způsob jak zjistit, zda je řetězec složen jen z malých písmen, -> je metoda `islower()`, která vrací True, pokud řetězec obsahuje jen malá -> písmena, jinak vrací False. Například `'abc'.islower() == True` ale -> `'aBc'.islower() == False`. -> -> Snadný způsob jak převést první písmenko na velké je metoda `capitalize()`: -> např. `'abc'.capitalize() == 'Abc'` - -{% filter solution %} -```python -def vyber_chybne(seznam): - vysledek = [] - for zaznam in seznam: - jmeno_a_prijmeni = zaznam.split(' ') - jmeno = jmeno_a_prijmeni[0] - prijmeni = jmeno_a_prijmeni[1] - if jmeno[0].islower() or prijmeni[0].islower(): - vysledek.append(zaznam) - return vysledek - -def vyber_spravne(seznam): - vysledek = [] - for zaznam in seznam: - jmeno_a_prijmeni = zaznam.split(' ') - jmeno = jmeno_a_prijmeni[0] - prijmeni = jmeno_a_prijmeni[1] - if not jmeno[0].islower() and not prijmeni[0].islower(): - vysledek.append(zaznam) - return vysledek - -def oprav_zaznamy(seznam): - vysledek = [] - for zaznam in seznam: - jmeno_a_prijmeni = zaznam.split(' ') - jmeno = jmeno_a_prijmeni[0] - prijmeni = jmeno_a_prijmeni[1] - vysledek.append(jmeno.capitalize() + ' ' + prijmeni.capitalize()) - return vysledek -``` -{% endfilter %} - ## Seznamy a náhoda Modul `random` obsahuje dvě funkce, které se hodí k seznamům. @@ -502,8 +459,8 @@ print(balicek) ``` A funkce `choice` ze seznamu vybere jeden náhodný prvek. -S použitím seznamu tak můžeme výrazně zjednodušit -úvodní část naší staré hry kámen/nůžky/papír: +S použitím seznamu tak můžeš třeba jednoduše vybrat tah pro hru +kámen/nůžky/papír: ```python import random diff --git a/lessons/beginners/list/static/methods.svg b/lessons/beginners/list/static/methods.svg new file mode 100644 index 0000000000..5c4b4ee862 --- /dev/null +++ b/lessons/beginners/list/static/methods.svg @@ -0,0 +1,1178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + .append( ) + + + + + + + + + + + + + + .extend( ) + + + + + + + + + + + + + + + + + + + .pop() + + + + + + + + + + + + + + .remove( ) + + + + + + + + + + + + + + + + + + + + + + .sort() + + + + + + + + + + + + + + + + + + + + + + .reverse() + + + + + + + + .clear() + + + + + + + + + + + .insert(2, ) + + + + + + + + + + + + + + + 0 + 1 + 2 + 3 + + + + Metody na změny seznamů + + + + + + + + + + diff --git a/lessons/beginners/tuple/index.md b/lessons/beginners/tuple/index.md index eec9cfeafc..c5eb2aec66 100644 --- a/lessons/beginners/tuple/index.md +++ b/lessons/beginners/tuple/index.md @@ -3,20 +3,24 @@ Když už známe seznam, podívejme se na jeho sestřičku: takzvanou n-tici (angl. *tuple*). -N-tice, podobně jako seznam, -může obsahovat n prvků. +N-tice může, podobně jako seznam, obsahovat n prvků. N-tice se dvěma prvky je *dvojice* neboli *pár* (angl. *pair*); se třemi prvky *trojice* (angl. *3-tuple*), se čtyřmi *čtveřice* (angl. *4-tuple*), atd. > [note] -> Existují i n-tice s jedním prvkem (hmm… „jednice”?) +> Pro úplnost: existují i n-tice s jedním prvkem (hmm… „jednice”?) > a s nula prvky (prázdné n-tice, angl. *empty tuple*), -> ale těmi se ze začátku nebudeme zabývat. +> ale ty nejsou příliš užitečné a v praxi se moc nepoužívají. N-tice se tvoří jako seznamy, jen kolem sebe nemají hranaté závorky. -Stačí čárky mezi prvky. +Stačí čárky mezi prvky: + +```python +dvojice = 'Pat', 'Mat' +print(dvojice) +``` Chovají se skoro stejně jako seznamy, jen nejdou měnit. Nemají tedy metody jako `append` @@ -28,13 +32,15 @@ a dají se z nich číst jednotlivé prvky. osoby = 'máma', 'teta', 'babička' for osoba in osoby: print(osoba) -print('První je {}'.format(osoby[0])) + +prvni = osoby[0] +print(f'První je {prvni}') ``` > [note] > Vypadá to povědomě? Aby ne! > N-tice jsme už použil{{gnd('i', 'y', both='i')}} dříve: -> `for jmeno in 'Hynek', 'Vilém', 'Jarmila':` +> `for pozdrav in 'Ahoj', 'Hello', 'Ciao':` > ve skutečnosti používá n-tici! Když chceš n-tici předat do funkce, @@ -64,11 +70,10 @@ def podil_a_zbytek(a, b): ``` > [note] -> Tahle funkce už mimochodem v Pythonu je: jmenuje se -> `divmod` a je vždy k dispozici -> (nemusí se importovat). +> Funkci „podíl a zbytek“ je mimochodem k dispozici přímo v Pythonu +> pod jménem `divmod`. -Python umí ještě jeden trik: pokud chceš přiřadit +Python umí ještě jeden trik, takzvané „rozbalení“: pokud chceš přiřadit do několika proměnných najednou, stačí je na levé straně rovnítka oddělit čárkou a na pravou stranu dát nějakou „složenou” hodnotu – třeba právě @@ -78,13 +83,16 @@ dát nějakou „složenou” hodnotu – třeba právě podil, zbytek = podil_a_zbytek(12, 5) ``` -N-tice se k tomuto účelu hodí nejvíc, ale -jde to se všemi hodnotami, které jdou použít ve `for`: +> [note] +> N-tice se k „rozbalování“ hodí nejvíc, protože mají +> daný počet prvků. +> Jde to ale použít se všemi hodnotami, které jdou použít ve `for`: +> +> ```python +> x, o = 'xo' +> jedna, dva, tri = [1, 2, 3] +> ``` -```python -x, o = 'xo' -jedna, dva, tri = [1, 2, 3] -``` ## Funkce, které vracejí n-tice From 7965a36521eacfaf0eb2251bb9e98d0277d0a2a8 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 8 Apr 2019 14:47:55 +0200 Subject: [PATCH 02/17] Add lessons on some special iterables: range, zip, enumerate --- courses/pyladies/info.yml | 6 + lessons/beginners/range/index.md | 98 ++++++++++++ lessons/beginners/range/info.yml | 4 + lessons/beginners/tuple/index.md | 42 ----- lessons/beginners/zip-enumerate/index.md | 195 +++++++++++++++++++++++ lessons/beginners/zip-enumerate/info.yml | 4 + 6 files changed, 307 insertions(+), 42 deletions(-) create mode 100644 lessons/beginners/range/index.md create mode 100644 lessons/beginners/range/info.yml create mode 100644 lessons/beginners/zip-enumerate/index.md create mode 100644 lessons/beginners/zip-enumerate/info.yml diff --git a/courses/pyladies/info.yml b/courses/pyladies/info.yml index 91720b809f..fe97d4bd59 100644 --- a/courses/pyladies/info.yml +++ b/courses/pyladies/info.yml @@ -104,6 +104,12 @@ plan: url: https://pyvec.github.io/cheatsheets/lists/lists-cs.pdf type: cheatsheet +- title: Iterujeme + slug: iteration + materials: + - lesson: beginners/range + - lesson: beginners/zip-enumerate + - title: Grafika slug: pyglet materials: diff --git a/lessons/beginners/range/index.md b/lessons/beginners/range/index.md new file mode 100644 index 0000000000..f069ac8129 --- /dev/null +++ b/lessons/beginners/range/index.md @@ -0,0 +1,98 @@ +# Range – sekvence čísel + +Funkce `range(10)` vrátí speciální hodnotu, +která v sobě obsahuje čísla od 0 do 9: + +```pycon +>>> sekvence = range(10) +>>> sekvence +range(0, 10) +``` + +Je to hodnota typu `range`, podobně jako čísla jsou typu `int`, řetězce typu +`str`, nebo seznamy typu `list`. + +Chceš-li se podívat, co v tomhle `range(0, 10)` vlastně je, máš dvě základní +možnosti – projít ho cyklem `for` nebo převést na seznam konkrétních čísel: + +```pycon +>>> sekvence +range(0, 10) +>>> for i in sekvence: +... print(i) +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +>>> list(sekvence) +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +``` + +Možná se ptáš – proč tak složitě? +Proč se místo `range(0, 10)` prostě ta čísla neukážou rovnou? + +Je to proto, že `range` se dá použít na opravdu dlouhé řady čísel: + +```pycon +>>> range(10000) +range(0, 10000) +>>> list(range(10000)) +[0, 1, 2, 3, ..., 9999] +``` + +Kdybys zkusil{{a}} třeba `list(range(1000000000000000000))`, počítači +dojde paměť. +Miliarda čísel se tam prostě nevejde. +Python vyhodí výjimku `MemoryError`. +Se samotným `range(1000000000000000000)` ale není problém. +S konceptem čísel od 0 do miliardy se počítač vypořádá, i když si je neumí +„zapamatovat“ všechny *najednou*. + +Je spousta věcí, které Python umí s `range` udělat, aniž by potřeboval +„spočítat“ každé z čísel. +Spousta operací, které znáš od seznamů, bude fungovat i s `range`: + +```pycon +>>> zajimava_cisla = range(8, 10000, 3) # Každé třetí číslo od 8 do 9999 +>>> zajimava_cisla[80] # Osmdesáté "zajímavé číslo" +248 +>>> zajimava_cisla[:5] # Prvních 5 "zajímavých čísel" +range(8, 23, 3) +>>> list(zajimava_cisla[:5]) # Vypsání prvních 5 "zajímavých čísel" +[8, 11, 14, 17, 20] +>>> len(zajimava_cisla) # Kolik tam je čísel? +3331 +>>> 1337 in zajimava_cisla # Je v této sekvenci moje konkrétní číslo ? +True +>>> zajimava_cisla.index(1337) # Kolikáté je? +443 +``` + +```pycon +>>> import random +>>> random.choice(zajimava_cisla) +1229 +``` + +```pycon +>>> for i in zajimava_cisla: +... print(i) +... if i > 20: +... break # Stačilo! +8 +11 +14 +17 +20 +23 +``` + +Objekt `range` ale nejde měnit – metody jako `zajimava_cisla.sort()`, +`zajimava_cisla.pop()` fungovat nebudou. + diff --git a/lessons/beginners/range/info.yml b/lessons/beginners/range/info.yml new file mode 100644 index 0000000000..10fbe5ccee --- /dev/null +++ b/lessons/beginners/range/info.yml @@ -0,0 +1,4 @@ +title: Range - sekvence čísel +style: md +attribution: Pro PyLadies Brno napsal Petr Viktorin, 2019. +license: cc-by-sa-40 diff --git a/lessons/beginners/tuple/index.md b/lessons/beginners/tuple/index.md index c5eb2aec66..e41ed6d036 100644 --- a/lessons/beginners/tuple/index.md +++ b/lessons/beginners/tuple/index.md @@ -94,48 +94,6 @@ podil, zbytek = podil_a_zbytek(12, 5) > ``` -## Funkce, které vracejí n-tice - -`zip` je zajímavá funkce. -Používá se ve `for` cyklech, podobně jako funkce `range`, která „dává” čísla. - -Když funkce `zip` dostane dva seznamy -(či jiné věci použitelné ve `for`), -„dává” dvojice, a to tak, že nejdřív spáruje -první prvek jednoho seznamu s prvním prvkem -druhého seznamu, -pak druhý s druhým, třetí s třetím a tak dál. - -Hodí se to, když máš dva seznamy se stejnou -strukturou – příslušné prvky k sobě „patří” -a chceš je zpracovávat společně: - -```python -osoby = 'máma', 'teta', 'babička', 'vrah' -vlastnosti = 'hodná', 'milá', 'laskavá', 'zákeřný' -for osoba, vlastnost in zip(osoby, vlastnosti): - print('{} je {}'.format(osoba, vlastnost)) -``` - -Když `zip` dostane tři seznamy, -bude tvořit trojice, ze čtyř seznamů nadělá čtveřice a tak dále. - -Další funkce, která vrací dvojice, je `enumerate`. -Jako argument bere seznam (či jinou věc použitelnou -ve `for`) a vždy spáruje index (pořadí v seznamu) s příslušným prvkem. -Jako první tedy dá -(0, *první prvek seznamu*), potom -(1, *druhý prvek seznamu*), -(2, *třetí prvek seznamu*) -a tak dále. - -```python -prvocisla = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] - -for i, prvocislo in enumerate(prvocisla): - print('Prvočíslo č.{} je {}'.format(i, prvocislo)) -``` - ## Malé n-tice Jak vytvořit n-tici s žádným nebo jedním prvkem? Takhle: diff --git a/lessons/beginners/zip-enumerate/index.md b/lessons/beginners/zip-enumerate/index.md new file mode 100644 index 0000000000..c20d105e2c --- /dev/null +++ b/lessons/beginners/zip-enumerate/index.md @@ -0,0 +1,195 @@ +# Iterátory n-tic + +Některé hodnoty v Pythonu jsou *iterovatelné* (angl. *iterable*): +obsahují sekvenci jiných hodnot a lze je „projít“ (iterovat) cyklem `for` nebo +je převést na seznam. +Už jich známe několik: + +```pycon +>>> list(range(10)) # sekvence čísel +>>> list('ahoj') # řetězec +>>> list(['Ahoj', 'Hello', 'Hei']) # seznam +>>> list((12, 'Sr', True)) # n-tice +``` + +Spousta těchto typů umí něco navíc: zjistit jestli obsahují nějaký prvek +(`4 in range(10)`), zjistit délku (`len([1, 2, 3])`), převést na velká písmena +(`'abc'.upper()`). +Nic z toho ale není potřeba, aby byl objekt iterovatelný. + +Podívejme se na dva dalších iterovatelné objekty: `enumerate` a `zip`. + + +## Enumerate: očíslování sekvence + +Funkce `enumerate` vezme nějakou existující sekvenci a *očísluje ji*: +ve vrácené sekvenci budou dvojice (index, původní hodnota). + +Řekněme že máš tento seznam: + +```python +trpaslici = ['Prófa', 'Stydlín', 'Dřímal', 'Kejchal', 'Štístko', + 'Šmudla', 'Rejpal'] +``` + +Když na něj použiješ `enumerate`, dostaneš objekt `enumerate`, +který podobně jako `range()` neukáže svůj obsah „rovnou“, +ale můžeš se „do něj“ podívat převedením na seznam. +Uvidíš tak seznam dvojic (číslo, trpaslík): + +```pycon +>>> enumerate(trpaslici) + +>>> list(enumerate(trpaslici)) +[(0, 'Prófa'), (1, 'Stydlín'), (2, 'Dřímal'), (3, 'Kejchal'), (4, 'Štístko'), (5, 'Šmudla'), (6, 'Rejpal')] +``` + +Místo převedení na seznam můžeš přes objekt `enumerate` iterovat cyklem `for` +a pro každou dvojici něco udělat. +Třeba ji hezky vypsat: + +```python +for dvojice in enumerate(trpaslici): + # Rozbalení dvojice + index, trpaslik = dvojice + # Vypsání + print(f'Na pozici {index} je {trpaslik}!') +``` + +Objekt, který funkce `enumerate` vrací, je *iterátor dvojic* – sekvence, +jejíž prvky jsou dvojice. + +## Rozbalování v cyklu for + +„Trpasličí“ cyklus se dá rozepsat takto: + +```python +dvojice = 0, 'Prófa' # toto dělá `for` +index, trpaslik = dvojice +print(f'Na pozici {index} je {trpaslik}!') + +dvojice = 1, 'Stydlín' # toto dělá `for` +index, trpaslik = dvojice +print(f'Na pozici {index} je {trpaslik}!') + +dvojice = 2, 'Dřímal' # toto dělá `for` +index, trpaslik = dvojice +print(f'Na pozici {index} je {trpaslik}!') + +# A tak dále +``` + +Kdybys to psal{{a}} ručně, lze to zjednodušit – přiřadit do dvou proměnných +najedno, bez pomocné `dvojice`: + +```python +index, trpaslik = 0, 'Prófa' # toto by mohl dělat `for` +print(f'Na pozici {index} je {trpaslik}!') + +index, trpaslik = 1, 'Stydlín' # toto by mohl dělat `for` +print(f'Na pozici {index} je {trpaslik}!') + +index, trpaslik = 2, 'Dřímal' # toto by mohl dělat `for` +print(f'Na pozici {index} je {trpaslik}!') + +# A tak dále +``` + +A `for` tohle ve skutečnosti umí: místo do proměnné `dvojice` může přiřadit +rovnou do dvou proměnných `index, trpaslik`: + +```python +for index, trpaslik in enumerate(trpaslici): + print(f'Na pozici {index} je {trpaslik}!') +``` + +Tohle je docela častẙ způsob práce s *iterátorem n-tic* – máš-li sekvenci, +jejíž prvky jsou n-tice, můžeš jednotlivé součásti n-tice +rozbalit přímo v hlavičce `for` cyklu. + +Zkus si to! Zkopíruj si tento seznam: + +```python +dny = ['Po', 'Út', 'St', 'Čt', 'Pá', 'So', 'Ne'] +``` + +… a zkus vypsat: + +```plain +1. Po +2. Út +3. St +4. Čt +5. Pá +6. So +7. Ne +``` + +{% filter solution %} + +```python +dny = ['Po', 'Út', 'St', 'Čt', 'Pá', 'So', 'Ne'] +for index, den in enumerate(dny): + cislo = index + 1 + print(f'{cislo}. {den}') +``` + +To je trošku kostrbaté, ale dá se to zjednodušit: funkce `enumerate` zná +pojmenovaný argument `start`, pomocí kterého umí sama +počítat od jiného začátku než od nuly: + +```python +dny = ['Po', 'Út', 'St', 'Čt', 'Pá', 'So', 'Ne'] +for index, den in enumerate(dny, start=1): + print(f'{index}. {den}') +``` + +{% endfilter %} + + +## Zip: Víc iterací najednou + +Další iterátor n-tic je funkce `zip`, která umí projít dvě sekvence +naráz. +Řekněme že máš seznam věcí a k nim příslušných barev: + +``` python +veci = ['tráva', 'slunce', 'mrkev', 'řeka'] +barvy = ['zelená', 'žluté', 'oranžová', 'modrá'] +``` + +Kdtyž tyto dva seznamy dáš funkci `zip`, dostaneš iterátor který příslušné +hodnoty spáruje. +Bude tedy obsahovat: + +* Dvojici prvních prvků obou seznamů +* Dvojici druhých prvků obou seznamů +* Dvojici třetích prvků obou seznamů +* ... + +``` python +for vec, barva in zip(veci, barvy): + print(f"{vec} je {barva}") +``` + +Funguje to i pro více sekvencí. +V následujícím případě je výsledný `zip` iterátor čtveřic (věc, barva, +místo, číslo): + +``` python +veci = ['tráva', 'slunce', 'mrkev', 'řeka'] +barvy = ['zelená', 'žluté', 'oranžová', 'modrá'] +mista = ['na zemi', 'nahoře', 'na talíři', 'za zídkou'] +cisla = range(4) + +for vec, barva, misto, cislo in zip(veci, barvy, mista, cisla): + print(f"{cislo}. {barva} {vec} je {misto}") +``` + +Když si ale vypíšeš samotný objekt `zip`, zjistíš že o sobě nic moc neřekne +– podobně jako `enumerate`: + +```pycon +>>> zip(veci, barvy, mista, cisla) + +``` diff --git a/lessons/beginners/zip-enumerate/info.yml b/lessons/beginners/zip-enumerate/info.yml new file mode 100644 index 0000000000..566e2e99ed --- /dev/null +++ b/lessons/beginners/zip-enumerate/info.yml @@ -0,0 +1,4 @@ +title: Iterátory n-tic +style: md +attribution: Pro PyLadies Brno napsal Petr Viktorin, 2014-2019. +license: cc-by-sa-40 From 0b1db6efbdd7ac9c38cff1b59e9643dc7e83dd8e Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 4 Nov 2019 17:17:35 +0100 Subject: [PATCH 03/17] Rewordings for Lists and Tuples --- lessons/beginners/list/index.md | 109 +++++++++++++++---------------- lessons/beginners/tuple/index.md | 33 +++++----- 2 files changed, 67 insertions(+), 75 deletions(-) diff --git a/lessons/beginners/list/index.md b/lessons/beginners/list/index.md index 9e16a9a363..da4b1dea8a 100644 --- a/lessons/beginners/list/index.md +++ b/lessons/beginners/list/index.md @@ -38,9 +38,9 @@ každá online služba má seznam uživatelů. Hodnoty v seznamu můžou být jakéhokoli typu. -Dokonce můžeme různé typy míchat v jednom seznamu +Dokonce můžeš různé typy míchat v jednom seznamu (i když s takovými namixovanými seznamy se -příliš často nesetkáme – více se různé typy hodnot +příliš často nesetkáš – více se různé typy hodnot používají v n-ticích, o kterých si povíme později): ```python @@ -65,12 +65,12 @@ print(kamaradka) ``` Proměnná `kamaradka` obsahuje řetězec `'Žaneta'` (který se už nedá změnit). -Metoda `upper()` vytvoří a vrátí *nový* řetězec. +Metoda `upper()` vytvoří a vrátí *nový* řetězec `'ŽANETA'`. Výsledná hodnota se ale v našem programu nevyužije – Python ji vypočítá, ale pak na ni „zapomene“. Oprava je snadná: výsledek uložit do proměnné. -Často budeš chtít takový výsledek uložit do původní proměnné: +Často budeš chtít takový výsledek uložit zpátky do původní proměnné: ```python kamaradka = kamaradka.upper() @@ -97,7 +97,7 @@ Ty se měnit dají. Základní způsob, jak změnit seznam, je přidání prvku na konec pomocí metody `append`. Ta *nic nevrací* (resp. vrací `None`), ale „na místě” (angl. *in place*) změní -seznam, na kterém pracuje. Vyzkoušej si to: +seznam, se kterým pracuje. Vyzkoušej si to: ```pycon >>> zviratka = ['pes', 'kočka', 'králík'] @@ -109,7 +109,7 @@ seznam, na kterém pracuje. Vyzkoušej si to: ``` Všimni si, že proměnná `zviratka` se nastavuje jen na začátku. -V celém programu výše jen jeden seznam – na začátku má tři prvky, pak +V celém programu výše je jen jeden seznam – na začátku má tři prvky, pak mu jeden přibude, ale stále je to jeden a ten samý seznam. Takové měnění může být občas překvapující, @@ -122,7 +122,7 @@ a = [1, 2, 3] # Vytvoření seznamu b = a # Tady se nový seznam nevytváří! # seznam vytvořený v prvním řádku má teď dvě jména: "a" a "b", -# ale stále pracujeme jenom s jedním seznamem +# ale stále pracuješ jenom s jedním seznamem print(b) a.append(4) @@ -132,8 +132,8 @@ print(b) ## Další způsoby, jak měnit seznamy Kromě metody `append`, která přidává jediný prvek na konec, existuje -spousta metod, které mění seznamy. -Všechny udělají přímo v daném seznamu, a (kromě `pop`) vrací `None`: +spousta dalších metod, které seznamy mění. +Všechny udělají změny přímo v daném seznamu a (kromě `pop`) vrací `None`: * `extend()` přidá více prvků najednou, * `insert()` přidá prvek na danou pozici, @@ -162,8 +162,7 @@ zviratka.clear() # [] Často budeš ze seznamu chtít vybrat prvek na určité pozici. To funguje jako u řetězců: do hranatých závorek dáš číslo prvku. -Stejně jako u řetězců se čísluje od nuly a záporná čísla označují prvky -od konce. +Stejně jako u řetězců se čísluje od nuly a záporná čísla číslují od konce. ```python zviratka = ['pes', 'kočka', 'králík'] @@ -171,10 +170,9 @@ print(zviratka[2]) ``` Hranatými závorkami můžeš získat i podseznam. -[Diagram z materiálů k řetězcům]({{ lesson_url('beginners/str')}}#slicing-diagram) +[Diagram z materiálů k řetězcům]({{ lesson_url('beginners/str')}}#slicing-diagram) ukazuje, jak u takového „sekání” číslovat: -funguje to stejně, jen místo menšího řetězce -dostaneš menší seznam. +funguje to stejně, jen místo menšího řetězce dostaneš menší seznam. ```python print(zviratka[2:-3]) @@ -209,8 +207,8 @@ print(zviratka) ### Mazání prvků -Přiřazením do podseznamu se dá i změnit délka -seznamu, nebo některé prvky úplně odstranit: +Přiřazením do podseznamu můžeš i změnit délku +seznamu nebo některé prvky úplně odstranit: ```python zviratka = ['pes', 'kočka', 'králík'] @@ -220,11 +218,12 @@ cisla[1:-1] = [] print(zviratka) ``` -Tenhle zápis pro mazání prvků je ale docela -nepřehledný, a proto na to máme zvláštní příkaz jménem `del`. +Tenhle zápis pro mazání prvků je ale docela nepřehledný +Proto na to existuje zvláštní příkaz jménem `del`. Jak už jeho název (z angl. *delete*, smazat) napovídá, smaže, co mu přijde pod ruku – jednotlivé prvky seznamů, podseznamy, … a dokonce i proměnné! +Zkus si: ```python zviratka = ['pes', 'kočka', 'králík', 'had', 'ještěrka', 'andulka'] @@ -241,10 +240,10 @@ del zviratka print(zviratka) ``` -Nebo můžeš použít mazací metody zmíněné výše: -* `pop`, která odstraní *a vrátí* poslední prvek v seznamu, -* `remove`, která najde v seznamu první výskyt daného prvku a odstraní ho, -* `clear`, která vyprázdní celý seznam. +Na mazání prvků můžeš použít i metody zmíněné výše: +* `pop` odstraní *a vrátí* poslední prvek v seznamu, +* `remove` najde v seznamu první výskyt daného prvku a odstraní ho, +* `clear` vyprázdní celý seznam. ```python balicek = ['eso', 'sedma', 'svršek', 'sedma', 'král'] @@ -261,7 +260,7 @@ print(balicek) ## Řazení -A taky tu máme metodu `sort`, která prvky seznamu seřadí. +Metoda `sort` seřadí prvky seznamu . ```python seznam = [4, 7, 8, 3, 5, 2, 4, 8, 5] @@ -270,13 +269,11 @@ print(seznam) ``` Aby se daly seřadit, musí být prvky seznamu vzájemně -*porovnatelné* – konktrétně na ně musí fungovat -operátor `<`. +*porovnatelné* – konktrétně na ně musí fungovat operátor `<`. Seznam s mixem čísel a řetězců tedy seřadit nepůjde. -Operátor `<` definuje i -jak přesně se řadí (např. čísla podle velikosti; +Operátor `<` definuje i jak přesně `sort` řadí: čísla podle velikosti; řetězce podle speciální „abecedy” která řadí -velká písmena za malá, česká až za anglická, atd.). +velká písmena za malá, česká až za anglická, atd. Metoda `sort` zná pojmenovaný argument `reverse`. Pokud ho nastavíš na *True*, řadí se „naopak”. @@ -289,7 +286,7 @@ print(seznam) ## Známé operace se seznamy -Spousta toho, co můžeme dělat s řetězci, má stejný +Spousta toho, co můžeš dělat s řetězci, má stejný účinek i u seznamů. Třeba sečítání a násobení číslem: @@ -298,7 +295,7 @@ melodie = ['C', 'E', 'G'] * 2 + ['E', 'E', 'D', 'E', 'F', 'D'] * 2 + ['E', 'D', print(melodie) ``` -Stejně jako u řetězců, sečítat jde jen seznam +Stejně jako u řetězců jde sečítat jen seznam se seznamem – ne třeba seznam s řetězcem. Další staří známí jsou funkce `len`, @@ -314,7 +311,7 @@ print('D' in melodie) # Je 'D' v seznamu? Poslední tři se ale přece jen chovají kapku jinak: u řetězců pracují s *podřetězci*, u seznamů jen s *jednotlivými* prvky. -Takže ačkoliv naše melodie obsahuje prvky +Takže ačkoliv melodie výše obsahuje prvky `'D'` a `'E'` vedle sebe, `'DE'` v seznamu není: ```python @@ -325,7 +322,7 @@ print(melodie.index('DE')) ## Seznam jako podmínka -Seznam se dá použít v příkazu `if` (nebo `while`) jako podmínka, +Seznam můžeš použít v příkazu `if` (nebo `while`) jako podmínka, která platí, když v tom seznamu něco je. Jinými slovy, `seznam` je tu „zkratka“ pro `len(seznam) > 0`. @@ -336,7 +333,7 @@ else: print('Seznam je prázdný!') ``` -Podobně se dají v podmínce použít i řetězce. +Podobně můžeš v podmínce použít i řetězce. A dokonce i čísla – ta jako podmínka platí, pokud jsou nenulová. ## Tvoření seznamů @@ -344,11 +341,10 @@ A dokonce i čísla – ta jako podmínka platí, pokud jsou nenulová. Tak jako funkce `int` převádí na celá čísla a `str` na řetězce, funkce `list` (angl. *seznam*) převádí na seznam. -Jako argument jí předáme jakoukoli hodnotu, +Jako argument jí můžeš předat jakoukoli hodnotu, kterou umí zpracovat příkaz `for`. Z řetězců udělá seznam znaků, z otevřeného souboru -udělá seznam řádků, z `range` udělá -seznam čísel. +udělá seznam řádků, z `range` udělá seznam čísel. ```python abeceda = list('abcdefghijklmnopqrstuvwxyz') @@ -358,8 +354,7 @@ print(cisla) ``` I ze seznamu udělá funkce `list` seznam. -To může znít zbytečně, ale není – vytvoří se -totiž *nový* seznam. +To může znít zbytečně, ale není – vytvoří se totiž *nový* seznam. Bude mít sice stejné prvky ve stejném pořadí, ale nebude to ten samý seznam: měnit se bude nezávisle na tom starém. @@ -371,13 +366,14 @@ b = list(a) print(b) a.append(4) print(b) +print(a) ``` Další způsob, jak tvořit seznamy (zvláště složitější), je nejdřív udělat prázdný seznam a pak ho postupně naplnit pomocí funkce `append`. Třeba pokud z nějakého důvodu chceš seznam -mocnin dvou, projdi čísla, kterými chceme mocnit, +mocnin dvou, projdi čísla, kterými chceš mocnit, cyklem `for` a pro každé z nich do seznamu přidej příslušnou mocninu: @@ -405,7 +401,7 @@ Seznamy a řetězce jsou druhy „sekvencí”, takže snad nepřekvapí, že se dá různě převádět z jednoho typu na druhý. Funkce `list` vytvoří z řetězce seznam znaků. -Když chceme dostat seznam slov, použijeme +Když chceš dostat seznam slov, použij na řetězci metodu `split` (angl. *rozdělit*): ```python @@ -414,8 +410,8 @@ print(slova) ``` Metoda `split` umí brát i argument. -Pokud ho předáme, místo mezer (a nových řádků) -se řetězec „rozseká” daným oddělovačem. +Pokud ho předáš řetězec „rozseká” daným oddělovačem +(místo mezer a nových řádků). Takže když máš nějaká data oddělená čárkami, použíj `split` s čárkou: @@ -427,9 +423,8 @@ print(zaznamy) Chceš-li spojit seznam řetězců zase dohromady do jediného řetězce, použij metodu `join` (angl. *spojit*). Pozor, tahle metoda se volá na *oddělovači*, -tedy řetězci, kterým se jednotlivé kousky „slepí” -dohromady; a jako argument bere seznam jednotlivých -řetězců. +tedy na řetězci, kterým se jednotlivé kousky „slepí” dohromady. +Seznam jednotlivých řetězců bere jako argument. ```python veta = ' '.join(slova) @@ -438,12 +433,12 @@ print(veta) ## Seznamy a náhoda -Modul `random` obsahuje dvě funkce, které se hodí k seznamům. -Jako `random.randrange`, obě mají něco -společného s náhodou. +Modul `random` obsahuje funkce, které mají něco společného s náhodou: +třeba nám už známou `random.randrange`. +Podívejme se na dvě další, které se hodí k seznamům. Funkce `shuffle` seznam „zamíchá” – všechny prvky náhodně popřehází. -Jako metoda `sort` i funkce `shuffle` nic nevrací. +Seznam změní „na místě“ a nic nevrací – podobně jako metoda `sort`. ```python import random @@ -479,9 +474,8 @@ Může třeba obsahovat i další seznamy: seznam_seznamu = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] ``` -Takový seznam se chová docela normálně – jdou -z něj třeba brát jednotlivé prvky -(které jsou ovšem taky seznamy): +Takový seznam se chová docela normálně – můžeš z něj třeba brát jednotlivé +prvky (které jsou ovšem taky seznamy): ```python prvni_seznam = seznam_seznamu[0] @@ -489,7 +483,7 @@ print(prvni_seznam) ``` A protože jsou prvky samy seznamy, -můžeme mluvit o věcech jako „první prvek druhého seznamu”: +dá se mluvit o věcech jako „první prvek druhého seznamu”: ```python druhy_seznam = seznam_seznamu[1] @@ -498,7 +492,7 @@ print(prvni_prvek_druheho_seznamu) ``` A protože výraz `seznam_seznamu[1]` -označuje seznam, můžeme brát prvky přímo z něj: +označuje seznam, můžeš brát prvky přímo z něj: ```python prvni_prvek_druheho_seznamu = (seznam_seznamu[1])[0] @@ -510,10 +504,9 @@ Neboli: prvni_prvek_druheho_seznamu = seznam_seznamu[1][0] ``` -A má tahle věc nějaké použití, ptáš se? -Stejně jako vnořené cykly `for` -nám umožnily vypsat tabulku, vnořené seznamy -nám umožní si tabulku „zapamatovat”. +A má tahle věc nějaké použití? +Stejně jako vnořené cykly `for` ti umožnily vypsat tabulku, vnořené seznamy +ti umožní si tabulku „zapamatovat”. ```python def vytvor_tabulku(velikost=11): diff --git a/lessons/beginners/tuple/index.md b/lessons/beginners/tuple/index.md index e41ed6d036..78e577a6a6 100644 --- a/lessons/beginners/tuple/index.md +++ b/lessons/beginners/tuple/index.md @@ -12,7 +12,7 @@ se čtyřmi *čtveřice* (angl. *4-tuple*), atd. > [note] > Pro úplnost: existují i n-tice s jedním prvkem (hmm… „jednice”?) > a s nula prvky (prázdné n-tice, angl. *empty tuple*), -> ale ty nejsou příliš užitečné a v praxi se moc nepoužívají. +> ale ty se v praxi tolik nepoužívají. N-tice se tvoří jako seznamy, jen kolem sebe nemají hranaté závorky. Stačí čárky mezi prvky: @@ -23,10 +23,8 @@ print(dvojice) ``` Chovají se skoro stejně jako seznamy, jen nejdou měnit. -Nemají tedy metody jako `append` -a `pop` a nedá se jim přiřazovat do prvků. -Dají se ale použít v cyklu `for` -a dají se z nich číst jednotlivé prvky. +Nemají tedy metody jako `append` a `pop` a nedá se jim přiřazovat do prvků. +Dají se ale použít v cyklu `for` a dají se z nich číst jednotlivé prvky. ```python osoby = 'máma', 'teta', 'babička' @@ -41,7 +39,7 @@ print(f'První je {prvni}') > Vypadá to povědomě? Aby ne! > N-tice jsme už použil{{gnd('i', 'y', both='i')}} dříve: > `for pozdrav in 'Ahoj', 'Hello', 'Ciao':` -> ve skutečnosti používá n-tici! +> ve skutečnosti používá n-tici. Když chceš n-tici předat do funkce, narazíš na problém, že čárka odděluje jednotlivé @@ -50,6 +48,10 @@ V podobných případech musíš n-tici uzavřít do závorek, aby bylo jasné, že jde o jednu hodnotu (byť složenou). +```python +print('osoby:', ('máma', 'teta', 'babička')) +``` + ```python seznam_dvojic = [] for i in range(10): @@ -60,8 +62,8 @@ print(seznam_dvojic) N-tice se hodí, pokud chceš z funkce vrátit víc než jednu hodnotu. -Prostě v příkazu `return` oddělíš vracené hodnoty čárkou. -Vypadá to, že vracíš několik hodnot, ale +Když příkazu `return` oddělíš vracené hodnoty čárkou, +vypadá to, že vracíš několik hodnot, ale ve skutečnosti se vrací jen jedna n-tice. ```python @@ -70,14 +72,13 @@ def podil_a_zbytek(a, b): ``` > [note] -> Funkci „podíl a zbytek“ je mimochodem k dispozici přímo v Pythonu +> Funkce „podíl a zbytek“ je mimochodem k dispozici přímo v Pythonu > pod jménem `divmod`. -Python umí ještě jeden trik, takzvané „rozbalení“: pokud chceš přiřadit -do několika proměnných najednou, stačí je na levé +Python umí ještě jeden trik, takzvané „rozbalení“ (angl. *unpacking*). +Když chceš přiřadit do několika proměnných najednou, stačí je na levé straně rovnítka oddělit čárkou a na pravou stranu -dát nějakou „složenou” hodnotu – třeba právě -n-tici. +dát nějakou „složenou” hodnotu – třeba právě n-tici. ```python podil, zbytek = podil_a_zbytek(12, 5) @@ -89,7 +90,7 @@ podil, zbytek = podil_a_zbytek(12, 5) > Jde to ale použít se všemi hodnotami, které jdou použít ve `for`: > > ```python -> x, o = 'xo' +> ix, ocko = 'xo' > jedna, dva, tri = [1, 2, 3] > ``` @@ -125,8 +126,7 @@ používá n-tici. různých typů, kdy má každá „pozice” v n-tici úplně jiný význam. Například seznam můžeš použít na písmena abecedy, -ale dvojice index–hodnota z `enumerate` -je n-tice. +ale dvojice „podíl a zbytek“ je n-tice. Prázdné n-tice a n-tice s jedním prvkem se zapisují trochu divně a má to své důvody: @@ -142,4 +142,3 @@ zjistíme že seznamy tam nepůjdou použít jako klíče. Často není úplně jasné, který typ použít – v takovém případě je to pravděpodobně jedno. -Řiď se instinktem. :) From 619fba019b69e07d59975d27877871ae72c932c2 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 6 Apr 2020 16:21:08 +0200 Subject: [PATCH 04/17] Prepare lesson on lists and tuples. Split out text on nested lists. --- courses/pyladies/info.yml | 1 + lessons/beginners/list/index.md | 151 ++++++++----------------- lessons/beginners/nested-list/index.md | 78 +++++++++++++ lessons/beginners/nested-list/info.yml | 4 + lessons/beginners/tuple/index.md | 24 ++-- 5 files changed, 145 insertions(+), 113 deletions(-) create mode 100644 lessons/beginners/nested-list/index.md create mode 100644 lessons/beginners/nested-list/info.yml diff --git a/courses/pyladies/info.yml b/courses/pyladies/info.yml index fe97d4bd59..f29c51834c 100644 --- a/courses/pyladies/info.yml +++ b/courses/pyladies/info.yml @@ -100,6 +100,7 @@ plan: materials: - lesson: beginners/list - lesson: beginners/tuple + - lesson: beginners/nested-list - title: Tahák na seznamy url: https://pyvec.github.io/cheatsheets/lists/lists-cs.pdf type: cheatsheet diff --git a/lessons/beginners/list/index.md b/lessons/beginners/list/index.md index da4b1dea8a..04db86523d 100644 --- a/lessons/beginners/list/index.md +++ b/lessons/beginners/list/index.md @@ -5,7 +5,9 @@ který si můžeš vytisknout. # Seznamy Dnes si ukážeme, jak pracovat se *seznamy* (angl. *lists*). -Zapisují se hranatými závorkami: + +Začneme prakticky. +Vytvoř si seznam pomocí následujícího kódu: ```python zviratka = ['pes', 'kočka', 'králík'] @@ -18,30 +20,32 @@ print(zviratka) Seznam je hodnota, která může obsahovat spoustu dalších hodnot. Tak jako řetězec obsahuje sekvenci znaků, -seznam obsahuje sekvenci... čehokoliv. Třeba slov (řetězců). -A tak jako můžeme pomocí cyklu `for` -procházet řetězec po znacích, -seznam můžeme procházet po jednotlivých prvcích: +seznam obsahuje sekvenci jakýchkoli hodnot. +V našem případě obsahuje sekvenci řetězců. + +A tak jako můžeš pomocí cyklu `for` procházet řetězec po znacích, +seznam můžeš procházet po jednotlivých prvcích: ```python for zviratko in zviratka: print(zviratko) ``` -Seznamy se v programech vyskytují velice často: -soubor se dá načíst jako seznam řetězců -s jednotlivými řádky, -seznam řetězců jako `'7♥'` -a `'K♣'` může posloužit jako balíček karet, -matematika je plná číselných řad, -každá online služba má seznam uživatelů. +Seznamy se v programech vyskytují často: +soubor se dá načíst jako seznam řetězců s jednotlivými řádky, +seznam řetězců jako `'7♥'` a `'K♣'` může posloužit jako balíček karet, +matematika je plná číselných řad, každá online služba má seznam uživatelů. + +Hodnoty v seznamu můžou být jakéhokoli typu: +```python +prvni_prvocisla = [2, 3, 5, 7, 11] +``` -Hodnoty v seznamu můžou být jakéhokoli typu. -Dokonce můžeš různé typy míchat v jednom seznamu -(i když s takovými namixovanými seznamy se -příliš často nesetkáš – více se různé typy hodnot -používají v n-ticích, o kterých si povíme později): +Dokonce můžeš různé typy míchat v jednom seznamu. +(S takovými namixovanými seznamy se ovšem příliš často nesetkáš. +Různé typy hodnot se používají spíš v n-ticích, o kterých si povíme +později): ```python seznam = [1, 'abc', True, None, range(10), len] @@ -109,13 +113,14 @@ seznam, se kterým pracuje. Vyzkoušej si to: ``` Všimni si, že proměnná `zviratka` se nastavuje jen na začátku. -V celém programu výše je jen jeden seznam – na začátku má tři prvky, pak -mu jeden přibude, ale stále je to jeden a ten samý seznam. +V rámci celého běhu programu výše existuje je jen jeden seznam. +Na začátku má tři prvky, pak mu jeden přibude, ale stále je to jeden a ten +samý seznam. Takové měnění může být občas překvapující, protože stejná hodnota může být přiřazená ve více proměnných. Protože se mění hodnota samotná, může to vypadat, -že se „mění proměnná, aniž na ni sáhneme”: +že se „mění proměnná, aniž na ni sáhneš”: ```python a = [1, 2, 3] # Vytvoření seznamu @@ -129,6 +134,7 @@ a.append(4) print(b) ``` + ## Další způsoby, jak měnit seznamy Kromě metody `append`, která přidává jediný prvek na konec, existuje @@ -139,7 +145,7 @@ Všechny udělají změny přímo v daném seznamu a (kromě `pop`) vrací `Non * `insert()` přidá prvek na danou pozici, * `pop()` odebere *a vrátí* poslední prvek, * `remove()` odstraní první výskyt daného prvku, -* `sort()` seznam seřadí (řetězce “podle abecedy”, čísla vzestupně), +* `sort()` seznam seřadí (řetězce podle “abecedy”, čísla vzestupně), * `reverse()` obrátí pořadí prvků, * `clear()` odstraní všechny prvky. @@ -340,11 +346,10 @@ A dokonce i čísla – ta jako podmínka platí, pokud jsou nenulová. Tak jako funkce `int` převádí na celá čísla a `str` na řetězce, -funkce `list` (angl. *seznam*) převádí na seznam. +funkce `list` převádí na seznam. Jako argument jí můžeš předat jakoukoli hodnotu, kterou umí zpracovat příkaz `for`. -Z řetězců udělá seznam znaků, z otevřeného souboru -udělá seznam řádků, z `range` udělá seznam čísel. +Z řetězců udělá seznam znaků, z `range` udělá seznam čísel. ```python abeceda = list('abcdefghijklmnopqrstuvwxyz') @@ -384,12 +389,22 @@ for cislo in range(10): print(mocniny_dvou) ``` +Podobným způsobem získáš seznam seznam `matka`, `babička`, `prababička`, +`praprababička`, atd.: + +```python +predkove = ['matka'] +for pocet_pra in range(10): + predkove.append('pra' * pocet_pra + 'babička') +print(predkove) +``` + Chceš-li seznam, který reprezentuje balíček karet, -zavolej `append` pro všechny kombinace barev a hodnot. +zavolej `append` pro všechny kombinace barev a hodnot: ```python balicek = [] -for barva in '♠', '♥', '♦', '♣': # (Na Windows použij textová jména) +for barva in '♠', '♥', '♦', '♣': for hodnota in list(range(2, 11)) + ['J', 'Q', 'K', 'A']: balicek.append(str(hodnota) + barva) print(balicek) @@ -397,9 +412,9 @@ print(balicek) ## Seznamy a řetězce -Seznamy a řetězce jsou druhy „sekvencí”, -takže snad nepřekvapí, že se dá různě převádět -z jednoho typu na druhý. +Seznamy a řetězce jsou druhy *sekvencí*. +Můžeš různě převádět z jednoho typu na druhý. + Funkce `list` vytvoří z řetězce seznam znaků. Když chceš dostat seznam slov, použij na řetězci metodu `split` (angl. *rozdělit*): @@ -438,7 +453,7 @@ třeba nám už známou `random.randrange`. Podívejme se na dvě další, které se hodí k seznamům. Funkce `shuffle` seznam „zamíchá” – všechny prvky náhodně popřehází. -Seznam změní „na místě“ a nic nevrací – podobně jako metoda `sort`. +Seznam změní „na místě“ a nic nevrací (podobně jako metoda `sort`). ```python import random @@ -454,84 +469,12 @@ print(balicek) ``` A funkce `choice` ze seznamu vybere jeden náhodný prvek. -S použitím seznamu tak můžeš třeba jednoduše vybrat tah pro hru +S použitím seznamu tak můžeš třeba jednoduše vybrat tah pro hru kámen/nůžky/papír: ```python import random mozne_tahy = ['kámen', 'nůžky', 'papír'] tah_pocitace = random.choice(mozne_tahy) +print(tah_pocitace) ``` - -## Vnořené seznamy - -A perlička na konec! -Na začátku tohoto textu je napsáno, že seznam -může obsahovat jakýkoli typ hodnot. -Může třeba obsahovat i další seznamy: - -```python -seznam_seznamu = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] -``` - -Takový seznam se chová docela normálně – můžeš z něj třeba brát jednotlivé -prvky (které jsou ovšem taky seznamy): - -```python -prvni_seznam = seznam_seznamu[0] -print(prvni_seznam) -``` - -A protože jsou prvky samy seznamy, -dá se mluvit o věcech jako „první prvek druhého seznamu”: - -```python -druhy_seznam = seznam_seznamu[1] -prvni_prvek_druheho_seznamu = druhy_seznam[0] -print(prvni_prvek_druheho_seznamu) -``` - -A protože výraz `seznam_seznamu[1]` -označuje seznam, můžeš brát prvky přímo z něj: - -```python -prvni_prvek_druheho_seznamu = (seznam_seznamu[1])[0] -``` - -Neboli: - -```python -prvni_prvek_druheho_seznamu = seznam_seznamu[1][0] -``` - -A má tahle věc nějaké použití? -Stejně jako vnořené cykly `for` ti umožnily vypsat tabulku, vnořené seznamy -ti umožní si tabulku „zapamatovat”. - -```python -def vytvor_tabulku(velikost=11): - seznam_radku = [] - for a in range(velikost): - radek = [] - for b in range(velikost): - radek.append(a * b) - seznam_radku.append(radek) - return seznam_radku - -nasobilka = vytvor_tabulku() - -print(nasobilka[2][3]) # dva krát tři -print(nasobilka[5][2]) # pět krát dva -print(nasobilka[8][7]) # osm krát sedm - -# Vypsání celé tabulky -for radek in nasobilka: - for cislo in radek: - print(cislo, end=' ') - print() -``` - -Co s takovou „zapamatovanou” tabulkou? -Můžeš si do ní uložit třeba pozice -figurek na šachovnici nebo křížků a koleček -ve *2D* piškvorkách. diff --git a/lessons/beginners/nested-list/index.md b/lessons/beginners/nested-list/index.md new file mode 100644 index 0000000000..5c092d310f --- /dev/null +++ b/lessons/beginners/nested-list/index.md @@ -0,0 +1,78 @@ +# Vnořené seznamy + +Seznam může obsahovat jakýkoli typ hodnot: čísla, řetězce, a tak dále: + +```python +prvocisla = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41] +zviratka = ['pes', 'kočka', 'králík'] +odpovedi = [False, False, False, True, False, True, True] +``` + +Stejně tak může seznam obsahovat i další seznamy. +Podobně jako seznam čísel nebo seznam řetězců tak lze vytvořit seznam seznamů: + +```python +seznam_seznamu = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] +``` + +Takový seznam se chová docela normálně – můžeš z něj třeba brát jednotlivé +prvky (které jsou ovšem taky seznamy): + +```python +prvni_seznam = seznam_seznamu[0] +print(prvni_seznam) +``` + +A protože jsou prvky samy seznamy, +dá se mluvit o věcech jako „první prvek druhého seznamu”: + +```python +druhy_seznam = seznam_seznamu[1] +prvni_prvek_druheho_seznamu = druhy_seznam[0] +print(prvni_prvek_druheho_seznamu) +``` + +A protože výraz `seznam_seznamu[1]` +označuje seznam, můžeš brát prvky přímo z něj: + +```python +prvni_prvek_druheho_seznamu = (seznam_seznamu[1])[0] +``` + +Neboli: + +```python +prvni_prvek_druheho_seznamu = seznam_seznamu[1][0] +``` + +A má tahle věc nějaké použití? +Stejně jako vnořené cykly `for` ti umožnily vypsat tabulku, vnořené seznamy +ti umožní si tabulku „zapamatovat”. + +```python +def vytvor_tabulku(velikost=11): + seznam_radku = [] + for a in range(velikost): + radek = [] + for b in range(velikost): + radek.append(a * b) + seznam_radku.append(radek) + return seznam_radku + +nasobilka = vytvor_tabulku() + +print(nasobilka[2][3]) # dva krát tři +print(nasobilka[5][2]) # pět krát dva +print(nasobilka[8][7]) # osm krát sedm + +# Vypsání celé tabulky +for radek in nasobilka: + for cislo in radek: + print(cislo, end=' ') + print() +``` + +Co s takovou „zapamatovanou” tabulkou? +Můžeš si do ní uložit třeba pozice +figurek na šachovnici nebo křížků a koleček +ve *2D* piškvorkách. diff --git a/lessons/beginners/nested-list/info.yml b/lessons/beginners/nested-list/info.yml new file mode 100644 index 0000000000..7167651c4a --- /dev/null +++ b/lessons/beginners/nested-list/info.yml @@ -0,0 +1,4 @@ +title: Vnořené seznamy +style: md +attribution: Pro PyLadies Brno napsal Petr Viktorin, 2014-2020. +license: cc-by-sa-40 diff --git a/lessons/beginners/tuple/index.md b/lessons/beginners/tuple/index.md index 78e577a6a6..79e282f687 100644 --- a/lessons/beginners/tuple/index.md +++ b/lessons/beginners/tuple/index.md @@ -23,8 +23,10 @@ print(dvojice) ``` Chovají se skoro stejně jako seznamy, jen nejdou měnit. -Nemají tedy metody jako `append` a `pop` a nedá se jim přiřazovat do prvků. -Dají se ale použít v cyklu `for` a dají se z nich číst jednotlivé prvky. +Nemají tedy metody jako `append` a `pop` a nedá se jim přiřazovat do prvků +(např. `ntice[1] = 2`). +Dají se ale použít v cyklu `for` a dají se z nich číst jednotlivé prvky +(např. `print(ntice[1])`). ```python osoby = 'máma', 'teta', 'babička' @@ -62,7 +64,7 @@ print(seznam_dvojic) N-tice se hodí, pokud chceš z funkce vrátit víc než jednu hodnotu. -Když příkazu `return` oddělíš vracené hodnoty čárkou, +Když u příkazu `return` použiješ vracených hodnoty oddělených čárkou, vypadá to, že vracíš několik hodnot, ale ve skutečnosti se vrací jen jedna n-tice. @@ -122,6 +124,10 @@ nebo seznam karet v balíčku. Oproti tomu `for pozdrav in 'Ahoj', 'Hello', 'Hola', 'Hei', 'SYN':` používá n-tici. +Když se počet prvků může v průběhu programu měnit, určitě sáhni po seznamu. +Příklad budiž seznam přihlášených uživatelů, nevyřešených požadavků, +karet v ruce nebo položek v inventáři. + N-tice se často používají na hodnoty různých typů, kdy má každá „pozice” v n-tici úplně jiný význam. @@ -133,12 +139,12 @@ prvkem se zapisují trochu divně a má to své důvody: může-li nastat situace, kdy takovou sekvenci budeš potřebovat, většinou je lepší sáhnout po seznamu. Například seznam hracích karet v ruce nebo -seznam lidí aktuálně přihlášených do soutěže -může být občas prázdný. +seznam lidí aktuálně sledujících video může být občas prázdný. Seznamy i n-tice mají i technické limity: -n-tice nejdou měnit a až se naučíme pracovat se slovníky, -zjistíme že seznamy tam nepůjdou použít jako klíče. +n-tice nejdou měnit a až se naučíš pracovat se slovníky, +zjistíš že seznamy tam nepůjdou použít jako klíče. +V takových případech je potřeba použít ten druhý typ sekvence. -Často není úplně jasné, který typ použít -– v takovém případě je to pravděpodobně jedno. +Často není úplně jasné, který typ použít. +V takovém případě je to pravděpodobně jedno. From 9f7dc6dcef7633c663adf8cebbfe6652bdc072fd Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 20 Jul 2020 17:47:41 +0200 Subject: [PATCH 05/17] Further nitpicks --- lessons/beginners/list/index.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lessons/beginners/list/index.md b/lessons/beginners/list/index.md index 04db86523d..b642ed1eef 100644 --- a/lessons/beginners/list/index.md +++ b/lessons/beginners/list/index.md @@ -73,7 +73,7 @@ Metoda `upper()` vytvoří a vrátí *nový* řetězec `'ŽANETA'`. Výsledná hodnota se ale v našem programu nevyužije – Python ji vypočítá, ale pak na ni „zapomene“. -Oprava je snadná: výsledek uložit do proměnné. +Oprava je snadná: výsledek si ulož do proměnné. Často budeš chtít takový výsledek uložit zpátky do původní proměnné: ```python @@ -176,7 +176,7 @@ print(zviratka[2]) ``` Hranatými závorkami můžeš získat i podseznam. -[Diagram z materiálů k řetězcům]({{ lesson_url('beginners/str')}}#slicing-diagram) +[Diagram z materiálů k řetězcům]({{ lesson_url('beginners/str-index-slice')}}#slicing-diagram) ukazuje, jak u takového „sekání” číslovat: funguje to stejně, jen místo menšího řetězce dostaneš menší seznam. @@ -282,7 +282,7 @@ Operátor `<` definuje i jak přesně `sort` řadí: čísla podle velikosti; velká písmena za malá, česká až za anglická, atd. Metoda `sort` zná pojmenovaný argument -`reverse`. Pokud ho nastavíš na *True*, řadí se „naopak”. +`reverse`. Pokud ho nastavíš na *True*, řadí se naopak. ```python seznam = [4, 7, 8, 3, 5, 2, 4, 8, 5] @@ -328,7 +328,7 @@ print(melodie.index('DE')) ## Seznam jako podmínka -Seznam můžeš použít v příkazu `if` (nebo `while`) jako podmínka, +Seznam můžeš použít v příkazu `if` (nebo `while`) jako podmínku, která platí, když v tom seznamu něco je. Jinými slovy, `seznam` je tu „zkratka“ pro `len(seznam) > 0`. @@ -349,7 +349,7 @@ celá čísla a `str` na řetězce, funkce `list` převádí na seznam. Jako argument jí můžeš předat jakoukoli hodnotu, kterou umí zpracovat příkaz `for`. -Z řetězců udělá seznam znaků, z `range` udělá seznam čísel. +Z řetězce udělá seznam znaků, z `range` udělá seznam čísel. ```python abeceda = list('abcdefghijklmnopqrstuvwxyz') From a5f91e2a9c6284508cb4514bd0f134ac48ff5d61 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 27 Jul 2020 15:03:01 +0200 Subject: [PATCH 06/17] Convert SVG texts to paths to avoid rendering issues --- lessons/beginners/list/static/methods.svg | 1797 +++++++++++---------- 1 file changed, 962 insertions(+), 835 deletions(-) diff --git a/lessons/beginners/list/static/methods.svg b/lessons/beginners/list/static/methods.svg index 5c4b4ee862..2c67d7dde8 100644 --- a/lessons/beginners/list/static/methods.svg +++ b/lessons/beginners/list/static/methods.svg @@ -1,113 +1,66 @@ - - + version="1.1" + viewBox="0 0 167.21666 135.46667" + height="512" + width="632"> + refY="0" + refX="0" + id="marker8073" + style="overflow:visible"> + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="matrix(-0.2,0,0,-0.2,-1.2,0)" /> + id="marker7754" + refX="0" + refY="0" + orient="auto"> + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path7752" /> + id="marker5829" + refX="0" + refY="0" + orient="auto"> + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path5827" /> + id="Arrow1Send" + refX="0" + refY="0" + orient="auto"> + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path1929" /> - - - @@ -121,1058 +74,1232 @@ + transform="translate(0,-161.56667)" + id="layer1"> - + x="78.374725" + y="269.50662" + rx="2.1166658" + ry="2.1166637" /> + + d="M 137.69077,191.14858 H 152.5196" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + .append( ) + transform="scale(1.0001519,0.99984812)" + aria-label=".append( )"> + + + + + + + + + + + d="m 10.585075,191.14862 c 1.114962,0 21.184275,0 21.184275,0" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + cx="14.821911" + id="path1896-6" + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + + cy="191.14854" + cx="27.532413" + id="circle1900-5" + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + d="M 10.585075,189.03082 H 8.4666566 v 4.23556 h 2.1184184" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="path5031" /> + id="path7632" /> - + id="circle7634" + cx="14.821951" + cy="201.7375" /> + + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle7638" + cx="27.532454" + cy="201.7375" /> + id="path7646" /> + d="m 38.124678,199.61974 h 2.118418 v 4.23556 h -2.118418" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + .extend( ) - + + + + + + + + + + + + id="path7664" /> - + id="circle7666" + cx="88.966774" + cy="191.14854" /> + + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle7670" + cx="101.67727" + cy="191.14854" /> + id="path7678" /> + d="m 105.91421,189.03082 h 2.11842 v 4.23556 h -2.11842" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + d="m 84.729978,201.73756 c 1.783938,0 33.894832,0 33.894832,0" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + cx="88.966812" + id="circle7684" + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + + + d="m 84.729974,199.61976 h -2.118418 v 4.23556 h 2.118418" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="path7698" /> - + cx="141.92746" + id="circle7702" + style="opacity:1;fill:#3fb0ac;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="opacity:1;fill:#3fb0ac;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle7704" + cx="148.2827" + cy="191.14861" /> + + style="opacity:1;fill:#3fb0ac;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle7710" + cx="114.38798" + cy="201.7375" /> + d="m 137.95561,189.03082 h -2.11842 v 4.23556 h 2.11842" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + .pop() - + + + + + + + + + id="path7724" /> - + id="circle7726" + cx="14.82196" + cy="220.79759" /> + + style="opacity:1;fill:#3fb0ac;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle7730" + cx="27.532463" + cy="220.79759" /> + id="path7732" /> + d="m 31.76921,218.67983 h 2.118418 v 4.23556 H 31.76921" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + d="m 10.585125,233.50435 c 0.780472,0 14.828945,0 14.828945,0" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle7740" + cx="21.177216" + cy="233.5043" /> + d="M 10.585125,231.38655 H 8.4667066 v 4.23555 h 2.1184184" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="path7746" /> + cy="233.50424" + cx="52.953617" + id="circle7748" + style="opacity:1;fill:#3fb0ac;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + .remove( ) + transform="scale(1.0001519,0.99984812)" + aria-label=".remove( )"> + + + + + + + + + + + d="m 84.729998,246.21105 c 1.783938,0 33.894812,0 33.894812,0" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle7970" + cx="95.32209" + cy="246.21097" /> + cy="246.21097" + cx="101.67733" + id="circle7972" + style="opacity:1;fill:#3fb0ac;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + d="M 84.729998,244.09325 H 82.61158 v 4.23555 h 2.118418" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="path7976" /> + id="path7978" /> - + + cy="256.79987" + cx="98.49971" + id="circle7982" + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="path7986" /> + d="m 115.44708,254.68217 h 2.11842 v 4.23555 h -2.11842" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + cy="246.21097" + cx="150.4012" + id="circle7992" + style="opacity:1;fill:#3fb0ac;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle7994" + cx="104.855" + cy="256.79987" /> + cy="256.79987" + cx="111.21029" + id="circle7996" + style="opacity:1;fill:#3fb0ac;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle8002" + cx="108.03269" + cy="246.21097" /> + cy="246.21097" + cx="114.38796" + id="circle8004" + style="opacity:1;fill:#3fb0ac;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#800000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="path8008" /> + id="path8021" /> - + - + .sort() + transform="scale(1.0001519,0.99984812)" + aria-label=".sort()"> + + + + + + + + + d="m 10.585101,248.32886 c 1.449449,0 27.539529,0 27.539529,0" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + cy="248.32883" + cx="14.821936" + id="circle8045" + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + id="circle8047" + cx="20.118004" + cy="248.32877" /> + + d="M 10.585101,246.21107 H 8.4666826 v 4.23555 h 2.1184184" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="path8053" /> + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle8069" + cx="33.887775" + cy="248.32883" /> + id="path8117" /> - + + cy="258.91772" + cx="19.764963" + id="circle8121" + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle8123" + cx="26.296774" + cy="258.91766" /> + id="path8125" /> + d="m 38.124648,256.79985 h 2.118418 v 4.23555 h -2.118418" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + cy="258.91772" + cx="33.887798" + id="circle8129" + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + d="m 84.729974,275.86002 c 1.449451,0 27.539526,0 27.539526,0" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + cx="88.437225" + id="circle8133" + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + + cy="275.85995" + cx="100.44164" + id="circle8137" + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + d="m 84.729974,273.74222 h -2.118418 v 4.23555 h 2.118418" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="path8141" /> - + .reverse() - + + + + + + + + + + + + + id="path8149" /> - - + + + transform="scale(-1,1)" + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle8155" + cx="-96.557884" + cy="286.44885" /> + id="path8157" /> + d="m 84.73001,284.33108 h -2.118418 v 4.23555 h 2.118418" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + .clear() - + + + + + + + + + + + id="path8173" /> - + id="circle8175" + cx="14.82192" + cy="275.85995" /> + + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle8179" + cx="27.532427" + cy="275.85995" /> + id="path8181" /> + d="m 31.76917,273.7422 h 2.118418 v 4.23555 H 31.76917" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + d="m 10.585085,286.44892 c 0.111497,0 2.118419,0 2.118419,0" + style="fill:none;stroke:#b3b3b3;stroke-width:0.26458332;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + d="M 10.585085,284.33112 H 8.4666666 v 4.23555 h 2.1184184" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="path8195" /> - + .insert(2, ) + transform="scale(1.0001519,0.99984812)" + aria-label=".insert(2, )"> + + + + + + + + + + + + + d="m 86.84841,218.67985 c 1.114967,0 21.18428,0 21.18428,0" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + cx="91.085258" + id="circle8223" + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + + cy="218.67972" + cx="103.79575" + id="circle8227" + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + d="m 86.84841,216.56206 h -2.11842 v 4.23555 h 2.11842" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="path8231" /> + cy="218.67972" + cx="148.2827" + id="circle8235" + style="opacity:1;fill:#3fb0ac;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="path8241" /> - + id="circle8243" + cx="87.9076" + cy="229.26862" /> + + style="opacity:1;fill:#3fb0ac;fill-opacity:1;stroke:#000000;stroke-width:0.52916664;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle8247" + cx="100.6181" + cy="229.26862" /> + id="path8249" /> + d="m 111.21033,227.15096 h 2.11842 v 4.23555 h -2.11842" + style="fill:none;stroke:#000000;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + 0 - + + + 1 - + + + 2 - + + + 3 - + transform="scale(1.0001519,0.99984812)" + aria-label="3"> + + + + d="m 96.91095,221.85649 -1.05922,4.23557" + style="fill:#b3b3b3;stroke:#b3b3b3;stroke-width:0.26458332;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + Metody na změny seznamů + transform="scale(1.0001519,0.99984812)" + aria-label="Metody na změny seznamů"> + + + + + + + + + + + + + + + + + + + + + - + d="m 21.17721,225.03314 v 4.23557" + id="path8290" /> + d="m 14.821931,194.32527 v 4.23558" + id="path8294" /> + + d="m 88.966864,194.32529 v 4.23558" + style="fill:#b3b3b3;stroke:#b3b3b3;stroke-width:0.26458332;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="path8302" /> From 38a829a556219ffe7d9532836dfe49a871096be2 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 8 Apr 2019 16:14:01 +0200 Subject: [PATCH 07/17] Add zip_longest --- lessons/beginners/zip-enumerate/index.md | 43 +++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/lessons/beginners/zip-enumerate/index.md b/lessons/beginners/zip-enumerate/index.md index c20d105e2c..9aa6b3529e 100644 --- a/lessons/beginners/zip-enumerate/index.md +++ b/lessons/beginners/zip-enumerate/index.md @@ -176,7 +176,7 @@ Funguje to i pro více sekvencí. V následujícím případě je výsledný `zip` iterátor čtveřic (věc, barva, místo, číslo): -``` python +```python veci = ['tráva', 'slunce', 'mrkev', 'řeka'] barvy = ['zelená', 'žluté', 'oranžová', 'modrá'] mista = ['na zemi', 'nahoře', 'na talíři', 'za zídkou'] @@ -193,3 +193,44 @@ Když si ale vypíšeš samotný objekt `zip`, zjistíš že o sobě nic moc ne >>> zip(veci, barvy, mista, cisla) ``` + + +## Zip Longest: Pro ty co chtějí všechno + +Jak se `zip` chová, když dostane seznamy různých délek? + +```python +veci = ['tráva', 'slunce', 'mrkev', 'řeka', 'myšlenka', 'spravedlnost'] +barvy = ['zelená', 'žluté', 'oranžová', 'modrá'] +for vec, barva in zip(veci, barvy): + print(f"{vec} je {barva}") +``` + +{% filter solution %} +Výsledek `zip` skončí hned když „dojde“ nejkratší sekvence. +{% endfilter %} + +Občas je potřeba projít všechny záznamy. +Na to slouží funkce `zip_longest` z modulu `itertools`: + +```python +from itertools import zip_longest +for vec, barva in zip_longest(veci, barvy, fillvalue='(nevím)'): + print(f"{vec} je {barva}") +``` + +Argument `fillvalue` říká, co se doplní za chybějící hodnoty. +Když ho nezadáš, doplní se `None` („nic“, hodnota kterou např. vrací procedury). +To se často používá, když je pro chybějící hodnoty potřeba nějaká +složitější logika: + +```python +from itertools import zip_longest +for vec, barva in zip_longest(veci, barvy): + if vec == None: + vec = 'nějaká věc' + if barva == None: + barva = 'bez barvy' + print(f"{vec} je {barva}") +``` + From 885e8b1019b84c9e272a6c833c462a4da02df162 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 11 Nov 2019 13:30:04 +0100 Subject: [PATCH 08/17] Reword lesson on zip & enumerate --- lessons/beginners/zip-enumerate/index.md | 36 +++++++++++++++--------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/lessons/beginners/zip-enumerate/index.md b/lessons/beginners/zip-enumerate/index.md index 9aa6b3529e..e50b5ec79c 100644 --- a/lessons/beginners/zip-enumerate/index.md +++ b/lessons/beginners/zip-enumerate/index.md @@ -17,7 +17,7 @@ Spousta těchto typů umí něco navíc: zjistit jestli obsahují nějaký prvek (`'abc'.upper()`). Nic z toho ale není potřeba, aby byl objekt iterovatelný. -Podívejme se na dva dalších iterovatelné objekty: `enumerate` a `zip`. +Podívejme se na dva další iterovatelné objekty: `enumerate` a `zip`. ## Enumerate: očíslování sekvence @@ -61,18 +61,20 @@ jejíž prvky jsou dvojice. ## Rozbalování v cyklu for -„Trpasličí“ cyklus se dá rozepsat takto: +Cyklus `for` umíme rozepsat: opakuje se v něm nastavení proměnné (které dělá +`for` za tebe), pak tělo cyklu, a znovu nastavení proměnné, tělo cyklu, atd. +Pro „trpasličí“ cyklus to je: ```python -dvojice = 0, 'Prófa' # toto dělá `for` +dvojice = 0, 'Prófa' # nastavení proměnné dělá `for` index, trpaslik = dvojice print(f'Na pozici {index} je {trpaslik}!') -dvojice = 1, 'Stydlín' # toto dělá `for` +dvojice = 1, 'Stydlín' # nastavení proměnné dělá `for` index, trpaslik = dvojice print(f'Na pozici {index} je {trpaslik}!') -dvojice = 2, 'Dřímal' # toto dělá `for` +dvojice = 2, 'Dřímal' # nastavení proměnné dělá `for` index, trpaslik = dvojice print(f'Na pozici {index} je {trpaslik}!') @@ -83,13 +85,13 @@ Kdybys to psal{{a}} ručně, lze to zjednodušit – přiřadit do dvou proměnn najedno, bez pomocné `dvojice`: ```python -index, trpaslik = 0, 'Prófa' # toto by mohl dělat `for` +index, trpaslik = 0, 'Prófa' # nastavení proměnných print(f'Na pozici {index} je {trpaslik}!') -index, trpaslik = 1, 'Stydlín' # toto by mohl dělat `for` +index, trpaslik = 1, 'Stydlín' # nastavení proměnných print(f'Na pozici {index} je {trpaslik}!') -index, trpaslik = 2, 'Dřímal' # toto by mohl dělat `for` +index, trpaslik = 2, 'Dřímal' # nastavení proměnných print(f'Na pozici {index} je {trpaslik}!') # A tak dále @@ -134,7 +136,8 @@ for index, den in enumerate(dny): print(f'{cislo}. {den}') ``` -To je trošku kostrbaté, ale dá se to zjednodušit: funkce `enumerate` zná +To je trošku kostrbaté, ale dá se to zjednodušit: buď jako +`f'{cislo + 1}. {den}'`, nebo můžeš funkci `enumerate` předat pojmenovaný argument `start`, pomocí kterého umí sama počítat od jiného začátku než od nuly: @@ -162,9 +165,9 @@ Kdtyž tyto dva seznamy dáš funkci `zip`, dostaneš iterátor který příslu hodnoty spáruje. Bude tedy obsahovat: -* Dvojici prvních prvků obou seznamů -* Dvojici druhých prvků obou seznamů -* Dvojici třetích prvků obou seznamů +* Dvojici prvních prvků obou seznamů: (`tráva`, `zelená`) +* Dvojici druhých prvků obou seznamů: (`slunce`, `žluté`) +* Dvojici třetích prvků obou seznamů: (`mrkev`, `oranžová`) * ... ``` python @@ -190,10 +193,17 @@ Když si ale vypíšeš samotný objekt `zip`, zjistíš že o sobě nic moc ne – podobně jako `enumerate`: ```pycon ->>> zip(veci, barvy, mista, cisla) +>>> zip(veci, barvy, cisla) ``` +Po převedení na seznam se ale seznam n-tic „ukáže”: + +```pycon +>>> list(zip(veci, barvy, cisla)) +[('tráva', 'zelená', 0), ('slunce', 'žluté', 1), ('mrkev', 'oranžová', 2), ('řeka', 'modrá', 3)] +``` + ## Zip Longest: Pro ty co chtějí všechno From bbb284f100a812794026a41bcd7393cac9500b0d Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 18 Nov 2019 15:27:42 +0100 Subject: [PATCH 09/17] Fix up zip-enumerate lesson --- lessons/beginners/zip-enumerate/index.md | 59 ++++++++++++------------ 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/lessons/beginners/zip-enumerate/index.md b/lessons/beginners/zip-enumerate/index.md index e50b5ec79c..25e6da240c 100644 --- a/lessons/beginners/zip-enumerate/index.md +++ b/lessons/beginners/zip-enumerate/index.md @@ -33,8 +33,8 @@ trpaslici = ['Prófa', 'Stydlín', 'Dřímal', 'Kejchal', 'Štístko', ``` Když na něj použiješ `enumerate`, dostaneš objekt `enumerate`, -který podobně jako `range()` neukáže svůj obsah „rovnou“, -ale můžeš se „do něj“ podívat převedením na seznam. +který podobně jako `range()` neukáže svůj obsah rovnou, +ale můžeš se „do něj podívat“ převedením na seznam. Uvidíš tak seznam dvojic (číslo, trpaslík): ```pycon @@ -82,7 +82,7 @@ print(f'Na pozici {index} je {trpaslik}!') ``` Kdybys to psal{{a}} ručně, lze to zjednodušit – přiřadit do dvou proměnných -najedno, bez pomocné `dvojice`: +najednou, bez pomocné proměnné `dvojice`: ```python index, trpaslik = 0, 'Prófa' # nastavení proměnných @@ -97,8 +97,8 @@ print(f'Na pozici {index} je {trpaslik}!') # A tak dále ``` -A `for` tohle ve skutečnosti umí: místo do proměnné `dvojice` může přiřadit -rovnou do dvou proměnných `index, trpaslik`: +Cyklus `for` tohle ve skutečnosti umí: místo do proměnné `dvojice` může +přiřadit rovnou do dvou proměnných `index, trpaslik`: ```python for index, trpaslik in enumerate(trpaslici): @@ -154,6 +154,7 @@ for index, den in enumerate(dny, start=1): Další iterátor n-tic je funkce `zip`, která umí projít dvě sekvence naráz. + Řekněme že máš seznam věcí a k nim příslušných barev: ``` python @@ -161,14 +162,27 @@ veci = ['tráva', 'slunce', 'mrkev', 'řeka'] barvy = ['zelená', 'žluté', 'oranžová', 'modrá'] ``` -Kdtyž tyto dva seznamy dáš funkci `zip`, dostaneš iterátor který příslušné -hodnoty spáruje. -Bude tedy obsahovat: +Když na ně zavoláš `zip`, dostaneš iterátor, který (podobně jako `enumerate` +nebo `range`) sám od sebe nic neříká: + +```pycon +>>> zip(veci, barvy) + +``` + +Po převedení na seznam se ale ukáže seznam odpovídajících si dvojic: + +* Dvojice prvních prvků obou seznamů: (`tráva`, `zelená`) +* Dvojice druhých prvků obou seznamů: (`slunce`, `žluté`) +* Dvojice třetích prvků obou seznamů: (`mrkev`, `oranžová`) +* A tak dál… + +```pycon +>>> list(zip(veci, barvy)) +[('tráva', 'zelená'), ('slunce', 'žluté'), ('mrkev', 'oranžová'), ('řeka', 'modrá')] +``` -* Dvojici prvních prvků obou seznamů: (`tráva`, `zelená`) -* Dvojici druhých prvků obou seznamů: (`slunce`, `žluté`) -* Dvojici třetích prvků obou seznamů: (`mrkev`, `oranžová`) -* ... +Takové dvojice jsou připravené na to, že je rozbalíš v cyklu `for`: ``` python for vec, barva in zip(veci, barvy): @@ -176,7 +190,7 @@ for vec, barva in zip(veci, barvy): ``` Funguje to i pro více sekvencí. -V následujícím případě je výsledný `zip` iterátor čtveřic (věc, barva, +V následujícím případě vznikne iterátor čtveřic (věc, barva, místo, číslo): ```python @@ -189,21 +203,6 @@ for vec, barva, misto, cislo in zip(veci, barvy, mista, cisla): print(f"{cislo}. {barva} {vec} je {misto}") ``` -Když si ale vypíšeš samotný objekt `zip`, zjistíš že o sobě nic moc neřekne -– podobně jako `enumerate`: - -```pycon ->>> zip(veci, barvy, cisla) - -``` - -Po převedení na seznam se ale seznam n-tic „ukáže”: - -```pycon ->>> list(zip(veci, barvy, cisla)) -[('tráva', 'zelená', 0), ('slunce', 'žluté', 1), ('mrkev', 'oranžová', 2), ('řeka', 'modrá', 3)] -``` - ## Zip Longest: Pro ty co chtějí všechno @@ -217,7 +216,7 @@ for vec, barva in zip(veci, barvy): ``` {% filter solution %} -Výsledek `zip` skončí hned když „dojde“ nejkratší sekvence. +Iterátor `zip` skončí hned když dojdou prvky nejkratší sekvence. {% endfilter %} Občas je potřeba projít všechny záznamy. @@ -229,7 +228,7 @@ for vec, barva in zip_longest(veci, barvy, fillvalue='(nevím)'): print(f"{vec} je {barva}") ``` -Argument `fillvalue` říká, co se doplní za chybějící hodnoty. +Pojmenovaný argument `fillvalue` říká, co se doplní za chybějící hodnoty. Když ho nezadáš, doplní se `None` („nic“, hodnota kterou např. vrací procedury). To se často používá, když je pro chybějící hodnoty potřeba nějaká složitější logika: From 82dbcb5613a65dd3d3937092d9c958466508b49e Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 20 Apr 2020 15:14:13 +0200 Subject: [PATCH 10/17] Adjust materials for range, zip, enumerate --- lessons/beginners/range/index.md | 47 ++++++++++++++++++++---- lessons/beginners/zip-enumerate/index.md | 35 +++++++++++++----- 2 files changed, 65 insertions(+), 17 deletions(-) diff --git a/lessons/beginners/range/index.md b/lessons/beginners/range/index.md index f069ac8129..39378f3273 100644 --- a/lessons/beginners/range/index.md +++ b/lessons/beginners/range/index.md @@ -46,13 +46,27 @@ range(0, 10000) [0, 1, 2, 3, ..., 9999] ``` -Kdybys zkusil{{a}} třeba `list(range(1000000000000000000))`, počítači +Kdybys zkusil{{a}} třeba `list(range(1000000000000000))`, počítači dojde paměť. -Miliarda čísel se tam prostě nevejde. +Biliarda čísel se tam prostě nevejde. Python vyhodí výjimku `MemoryError`. -Se samotným `range(1000000000000000000)` ale není problém. -S konceptem čísel od 0 do miliardy se počítač vypořádá, i když si je neumí -„zapamatovat“ všechny *najednou*. + + +> [warning] +> Pokud máš na počítači v jiném okně neuloženou práci, radši `list(range(...))` +> s hodně vysokými čísly nezkoušej. +> +> U absurdně vysokého čísla jako `1000000000000000` Python předem ví, +> že mu paměť dojde, a tak ohlásí chybu ještě než se bude snažit seznam vytvořit. +> U trochu menšího čísla (např. `1000000000`, ale na každém počítači je to +> jinak) se může stát, že se Python pokusí seznam začít tvořit, zaplní přitom +> většinu dostupné paměti a počítač „zamrzne“. +> V závislosti na systému se pak třeba může stát že reakce na +> Ctrl+C bude trvat hodně dlouho. + +Se samotným `range(1000000000000000)` ale není problém. +S konceptem *všech čísel od 0 do biliardy* se počítač vypořádá, i když si je +neumí „zapamatovat“ všechny *najednou*. Je spousta věcí, které Python umí s `range` udělat, aniž by potřeboval „spočítat“ každé z čísel. @@ -93,6 +107,25 @@ True 23 ``` -Objekt `range` ale nejde měnit – metody jako `zajimava_cisla.sort()`, -`zajimava_cisla.pop()` fungovat nebudou. +Objekt `range` ale nejde měnit – mazání prvků nebo metody jako +`zajimava_cisla.sort()`, `zajimava_cisla.pop()` fungovat nebudou. + +> [note] Proč ne? +> Když máš objekt jako `range(8, 10000, 3)`, osmdesátý prvek je jen trocha +> matematiky: spočítáš `8 + 3 * 80` a zkontroluješ že to nepřesáhlo `10000`. +> Podobně je to s ostatními sekvencemi „všech X-tých čísel od +> A do B“, tedy s ostatními `range`. +> +> Kdyby ale šlo udělat něco jako: +> +> ```python +> sekvence = range(8, 10000, 3) +> del sekvence[10] +> sekvence.insert(103, 'ježek') +> ``` +> +> … jde najednou o mnohem složitější koncept, kde se N-tý prvek hledá mnohem +> hůř. Už to není jednoduchá sekvence čísel – už to není `range`, ale spíš +> seznam jakýchkoli hodnot. +Pokud budeš něco co `range` neumí potřebovat, převeď `range` na seznam. diff --git a/lessons/beginners/zip-enumerate/index.md b/lessons/beginners/zip-enumerate/index.md index 25e6da240c..103eabc1f1 100644 --- a/lessons/beginners/zip-enumerate/index.md +++ b/lessons/beginners/zip-enumerate/index.md @@ -18,6 +18,7 @@ Spousta těchto typů umí něco navíc: zjistit jestli obsahují nějaký prvek Nic z toho ale není potřeba, aby byl objekt iterovatelný. Podívejme se na dva další iterovatelné objekty: `enumerate` a `zip`. +Oba jsou sekvence vytvořené z jiných, jednodušších sekvencí. ## Enumerate: očíslování sekvence @@ -59,9 +60,23 @@ for dvojice in enumerate(trpaslici): Objekt, který funkce `enumerate` vrací, je *iterátor dvojic* – sekvence, jejíž prvky jsou dvojice. +Sekvence `enumerate` toho „umí“ ještě míň než seznam nebo `range`. +Nejde z ní ani vybírat prvky, o metodách jako `append` ani nemluvě: + +```pycon +>>> enumerate(trpaslici)[3] +Traceback (most recent call last): + File "", line 1, in +TypeError: 'enumerate' object is not subscriptable +``` + +Když budeš od sekvence `enumerate` chtít něco víc než iterování, +převeď ji na seznam. + + ## Rozbalování v cyklu for -Cyklus `for` umíme rozepsat: opakuje se v něm nastavení proměnné (které dělá +Cyklus `for` umíš rozepsat: opakuje se v něm nastavení proměnné (které dělá `for` za tebe), pak tělo cyklu, a znovu nastavení proměnné, tělo cyklu, atd. Pro „trpasličí“ cyklus to je: @@ -155,11 +170,11 @@ for index, den in enumerate(dny, start=1): Další iterátor n-tic je funkce `zip`, která umí projít dvě sekvence naráz. -Řekněme že máš seznam věcí a k nim příslušných barev: +Řekněme že máš seznam věcí a druhý seznam, ve kterém jsou barvy těch věcí: ``` python -veci = ['tráva', 'slunce', 'mrkev', 'řeka'] -barvy = ['zelená', 'žluté', 'oranžová', 'modrá'] +veci = ['tráva', 'slunce', 'mrkev', 'list'] +barvy = ['zelená', 'žluté', 'oranžová', 'zelený'] ``` Když na ně zavoláš `zip`, dostaneš iterátor, který (podobně jako `enumerate` @@ -179,7 +194,7 @@ Po převedení na seznam se ale ukáže seznam odpovídajících si dvojic: ```pycon >>> list(zip(veci, barvy)) -[('tráva', 'zelená'), ('slunce', 'žluté'), ('mrkev', 'oranžová'), ('řeka', 'modrá')] +[('tráva', 'zelená'), ('slunce', 'žluté'), ('mrkev', 'oranžová'), ('list', 'zelený')] ``` Takové dvojice jsou připravené na to, že je rozbalíš v cyklu `for`: @@ -194,9 +209,9 @@ V následujícím případě vznikne iterátor čtveřic (věc, barva, místo, číslo): ```python -veci = ['tráva', 'slunce', 'mrkev', 'řeka'] -barvy = ['zelená', 'žluté', 'oranžová', 'modrá'] -mista = ['na zemi', 'nahoře', 'na talíři', 'za zídkou'] +veci = ['tráva', 'slunce', 'mrkev', 'list'] +barvy = ['zelená', 'žluté', 'oranžová', 'zelený'] +mista = ['na zemi', 'nahoře', 'na talíři', 'na stromě'] cisla = range(4) for vec, barva, misto, cislo in zip(veci, barvy, mista, cisla): @@ -209,8 +224,8 @@ for vec, barva, misto, cislo in zip(veci, barvy, mista, cisla): Jak se `zip` chová, když dostane seznamy různých délek? ```python -veci = ['tráva', 'slunce', 'mrkev', 'řeka', 'myšlenka', 'spravedlnost'] -barvy = ['zelená', 'žluté', 'oranžová', 'modrá'] +veci = ['tráva', 'slunce', 'mrkev', 'list', 'myšlenka', 'spravedlnost'] +barvy = ['zelená', 'žluté', 'oranžová', 'zelený'] for vec, barva in zip(veci, barvy): print(f"{vec} je {barva}") ``` From 5ee6c04661b21a498ec7608f1527de437efac267 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 3 Aug 2020 15:10:32 +0200 Subject: [PATCH 11/17] Apply fixes from code review Co-authored-by: Glutexo Co-authored-by: adelpopelkova <59389471+adelpopelkova@users.noreply.github.com> --- lessons/beginners/list/index.md | 20 ++++++++++---------- lessons/beginners/nested-list/index.md | 2 +- lessons/beginners/range/index.md | 2 +- lessons/beginners/tuple/index.md | 2 +- lessons/beginners/zip-enumerate/index.md | 5 ++--- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/lessons/beginners/list/index.md b/lessons/beginners/list/index.md index b642ed1eef..0cacbe3dab 100644 --- a/lessons/beginners/list/index.md +++ b/lessons/beginners/list/index.md @@ -71,7 +71,7 @@ print(kamaradka) Proměnná `kamaradka` obsahuje řetězec `'Žaneta'` (který se už nedá změnit). Metoda `upper()` vytvoří a vrátí *nový* řetězec `'ŽANETA'`. Výsledná hodnota se ale v našem programu nevyužije – Python ji vypočítá, -ale pak na ni „zapomene“. +ale pak ji „zapomene“. Oprava je snadná: výsledek si ulož do proměnné. Často budeš chtít takový výsledek uložit zpátky do původní proměnné: @@ -80,7 +80,7 @@ Oprava je snadná: výsledek si ulož do proměnné. kamaradka = kamaradka.upper() ``` -Tímto přiřazením Python „zapomene“ na původní hodnotu, +Tímto přiřazením Python „zapomene“ původní hodnotu, a od tohoto příkazu dál bude proměnná `kamaradka` označovat nový řetězec. Podobně by se dala proměnná přenastavit na jakoukoli jinou hodnotu: @@ -113,7 +113,7 @@ seznam, se kterým pracuje. Vyzkoušej si to: ``` Všimni si, že proměnná `zviratka` se nastavuje jen na začátku. -V rámci celého běhu programu výše existuje je jen jeden seznam. +V rámci celého běhu programu výše existuje jen jeden seznam. Na začátku má tři prvky, pak mu jeden přibude, ale stále je to jeden a ten samý seznam. @@ -190,7 +190,7 @@ to neprojeví. ### Měnění prvků -Na rozdíl od řetězců (které se nedají měnit) můžeš u existujících seznamů +Na rozdíl od řetězců (které se měnit nedají) můžeš u existujících seznamů nastavovat konkrétní prvky – a to tak, že do prvku přiřadíš jako by to byla proměnná: @@ -206,7 +206,7 @@ co přiřadíš. ```python zviratka = ['pes', 'kočka', 'králík', 'had', 'andulka'] -print([1:-1]) +print(zviratka[1:-1]) zviratka[1:-1] = ['koťátko', 'králíček', 'hádě'] print(zviratka) ``` @@ -220,11 +220,11 @@ seznamu nebo některé prvky úplně odstranit: zviratka = ['pes', 'kočka', 'králík'] zviratka[1:-1] = ['had', 'ještěrka', 'drak'] print(zviratka) -cisla[1:-1] = [] +zviratka[1:-1] = [] print(zviratka) ``` -Tenhle zápis pro mazání prvků je ale docela nepřehledný +Tenhle zápis pro mazání prvků je ale docela nepřehledný. Proto na to existuje zvláštní příkaz jménem `del`. Jak už jeho název (z angl. *delete*, smazat) napovídá, smaže, co mu přijde pod ruku – jednotlivé @@ -247,7 +247,7 @@ print(zviratka) ``` Na mazání prvků můžeš použít i metody zmíněné výše: -* `pop` odstraní *a vrátí* poslední prvek v seznamu, +* `pop` odstraní poslední prvek v seznamu a *vrátí* ho, * `remove` najde v seznamu první výskyt daného prvku a odstraní ho, * `clear` vyprázdní celý seznam. @@ -266,7 +266,7 @@ print(balicek) ## Řazení -Metoda `sort` seřadí prvky seznamu . +Metoda `sort` seřadí prvky seznamu. ```python seznam = [4, 7, 8, 3, 5, 2, 4, 8, 5] @@ -425,7 +425,7 @@ print(slova) ``` Metoda `split` umí brát i argument. -Pokud ho předáš řetězec „rozseká” daným oddělovačem +Pokud ho předáš, řetězec „rozseká” daným oddělovačem (místo mezer a nových řádků). Takže když máš nějaká data oddělená čárkami, použíj `split` s čárkou: diff --git a/lessons/beginners/nested-list/index.md b/lessons/beginners/nested-list/index.md index 5c092d310f..588a457771 100644 --- a/lessons/beginners/nested-list/index.md +++ b/lessons/beginners/nested-list/index.md @@ -1,6 +1,6 @@ # Vnořené seznamy -Seznam může obsahovat jakýkoli typ hodnot: čísla, řetězce, a tak dále: +Seznam může obsahovat jakýkoli typ hodnot: čísla, řetězce a tak dále: ```python prvocisla = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41] diff --git a/lessons/beginners/range/index.md b/lessons/beginners/range/index.md index 39378f3273..53b52e3bd3 100644 --- a/lessons/beginners/range/index.md +++ b/lessons/beginners/range/index.md @@ -128,4 +128,4 @@ Objekt `range` ale nejde měnit – mazání prvků nebo metody jako > hůř. Už to není jednoduchá sekvence čísel – už to není `range`, ale spíš > seznam jakýchkoli hodnot. -Pokud budeš něco co `range` neumí potřebovat, převeď `range` na seznam. +Pokud budeš něco, co `range` neumí, potřebovat, převeď `range` na seznam. diff --git a/lessons/beginners/tuple/index.md b/lessons/beginners/tuple/index.md index 79e282f687..0d34379bff 100644 --- a/lessons/beginners/tuple/index.md +++ b/lessons/beginners/tuple/index.md @@ -64,7 +64,7 @@ print(seznam_dvojic) N-tice se hodí, pokud chceš z funkce vrátit víc než jednu hodnotu. -Když u příkazu `return` použiješ vracených hodnoty oddělených čárkou, +Když u příkazu `return` použiješ několik hodnot oddělených čárkou, vypadá to, že vracíš několik hodnot, ale ve skutečnosti se vrací jen jedna n-tice. diff --git a/lessons/beginners/zip-enumerate/index.md b/lessons/beginners/zip-enumerate/index.md index 103eabc1f1..cd748d2227 100644 --- a/lessons/beginners/zip-enumerate/index.md +++ b/lessons/beginners/zip-enumerate/index.md @@ -77,7 +77,7 @@ převeď ji na seznam. ## Rozbalování v cyklu for Cyklus `for` umíš rozepsat: opakuje se v něm nastavení proměnné (které dělá -`for` za tebe), pak tělo cyklu, a znovu nastavení proměnné, tělo cyklu, atd. +`for` za tebe), pak tělo cyklu, a znovu nastavení proměnné, tělo cyklu atd. Pro „trpasličí“ cyklus to je: ```python @@ -120,7 +120,7 @@ for index, trpaslik in enumerate(trpaslici): print(f'Na pozici {index} je {trpaslik}!') ``` -Tohle je docela častẙ způsob práce s *iterátorem n-tic* – máš-li sekvenci, +Tohle je docela častý způsob práce s *iterátorem n-tic* – máš-li sekvenci, jejíž prvky jsou n-tice, můžeš jednotlivé součásti n-tice rozbalit přímo v hlavičce `for` cyklu. @@ -257,4 +257,3 @@ for vec, barva in zip_longest(veci, barvy): barva = 'bez barvy' print(f"{vec} je {barva}") ``` - From f238ecf44e3840683057e26a11a2747a80cf90bf Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 10 Aug 2020 14:23:03 +0200 Subject: [PATCH 12/17] Apply suggestions from code review Co-authored-by: adelpopelkova <59389471+adelpopelkova@users.noreply.github.com> --- lessons/beginners/list/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lessons/beginners/list/index.md b/lessons/beginners/list/index.md index 0cacbe3dab..683224bb57 100644 --- a/lessons/beginners/list/index.md +++ b/lessons/beginners/list/index.md @@ -34,7 +34,7 @@ for zviratko in zviratka: Seznamy se v programech vyskytují často: soubor se dá načíst jako seznam řetězců s jednotlivými řádky, seznam řetězců jako `'7♥'` a `'K♣'` může posloužit jako balíček karet, -matematika je plná číselných řad, každá online služba má seznam uživatelů. +matematika je plná číselných řad, e-shopy pracují se seznamy zboží. Hodnoty v seznamu můžou být jakéhokoli typu: @@ -71,7 +71,7 @@ print(kamaradka) Proměnná `kamaradka` obsahuje řetězec `'Žaneta'` (který se už nedá změnit). Metoda `upper()` vytvoří a vrátí *nový* řetězec `'ŽANETA'`. Výsledná hodnota se ale v našem programu nevyužije – Python ji vypočítá, -ale pak ji „zapomene“. +ale pak ji „zahodí“. Oprava je snadná: výsledek si ulož do proměnné. Často budeš chtít takový výsledek uložit zpátky do původní proměnné: @@ -80,7 +80,7 @@ Oprava je snadná: výsledek si ulož do proměnné. kamaradka = kamaradka.upper() ``` -Tímto přiřazením Python „zapomene“ původní hodnotu, +Tímto přiřazením Python „zahodí“ původní hodnotu, a od tohoto příkazu dál bude proměnná `kamaradka` označovat nový řetězec. Podobně by se dala proměnná přenastavit na jakoukoli jinou hodnotu: @@ -184,7 +184,7 @@ funguje to stejně, jen místo menšího řetězce dostaneš menší seznam. print(zviratka[2:-3]) ``` -„Sekáním“ vzniká nový seznam – když pak ten původní změníš, v podseznamu se +„Sekáním“ vzniká nový seznam – když pak ten původní změníš, v novém menším seznamu se to neprojeví. From b6d8f0454a3eb3174ead7907084be4861a5b779a Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 10 Aug 2020 14:53:13 +0200 Subject: [PATCH 13/17] list.sort: Be more explicit about increasing/decreasing order --- lessons/beginners/list/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lessons/beginners/list/index.md b/lessons/beginners/list/index.md index 683224bb57..b0e3749dde 100644 --- a/lessons/beginners/list/index.md +++ b/lessons/beginners/list/index.md @@ -277,12 +277,12 @@ print(seznam) Aby se daly seřadit, musí být prvky seznamu vzájemně *porovnatelné* – konktrétně na ně musí fungovat operátor `<`. Seznam s mixem čísel a řetězců tedy seřadit nepůjde. -Operátor `<` definuje i jak přesně `sort` řadí: čísla podle velikosti; -řetězce podle speciální „abecedy” která řadí +Operátor `<` definuje i jak přesně `sort` řadí: čísla vzestupně podle +velikosti; řetězce podle speciální „abecedy” která řadí velká písmena za malá, česká až za anglická, atd. -Metoda `sort` zná pojmenovaný argument -`reverse`. Pokud ho nastavíš na *True*, řadí se naopak. +Metoda `sort` zná pojmenovaný argument `reverse`. +Pokud ho nastavíš na *True*, řadí se naopak – od největšího prvku po nejmenší. ```python seznam = [4, 7, 8, 3, 5, 2, 4, 8, 5] From 58b6522e83649cc405af9fa3df7b747974fa980b Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 10 Aug 2020 14:55:30 +0200 Subject: [PATCH 14/17] Mention that sublists aren't `in` a list --- lessons/beginners/list/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lessons/beginners/list/index.md b/lessons/beginners/list/index.md index b0e3749dde..6425108e09 100644 --- a/lessons/beginners/list/index.md +++ b/lessons/beginners/list/index.md @@ -318,7 +318,7 @@ Poslední tři se ale přece jen chovají kapku jinak: u řetězců pracují s *podřetězci*, u seznamů jen s *jednotlivými* prvky. Takže ačkoliv melodie výše obsahuje prvky -`'D'` a `'E'` vedle sebe, `'DE'` v seznamu není: +`'D'` a `'E'` vedle sebe, `'DE'` ani `['D', 'E']` v seznamu není: ```python print('DE' in melodie) From 57dd5ecc322ab9e202592b5730bca1b6dd23aa42 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 10 Aug 2020 14:56:23 +0200 Subject: [PATCH 15/17] Clarify operand order --- lessons/beginners/list/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lessons/beginners/list/index.md b/lessons/beginners/list/index.md index 6425108e09..0f6fe0db5b 100644 --- a/lessons/beginners/list/index.md +++ b/lessons/beginners/list/index.md @@ -395,7 +395,7 @@ Podobným způsobem získáš seznam seznam `matka`, `babička`, `prababička`, ```python predkove = ['matka'] for pocet_pra in range(10): - predkove.append('pra' * pocet_pra + 'babička') + predkove.append(('pra' * pocet_pra) + 'babička') print(predkove) ``` From 78891ea030a8911e146d54ab2771d45277dcec52 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 10 Aug 2020 15:30:56 +0200 Subject: [PATCH 16/17] Make deck-building code more straightforward Optimization is left as an exercise, but also given a bit later. --- lessons/beginners/list/index.md | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/lessons/beginners/list/index.md b/lessons/beginners/list/index.md index 0f6fe0db5b..57b5acca1d 100644 --- a/lessons/beginners/list/index.md +++ b/lessons/beginners/list/index.md @@ -405,11 +405,31 @@ zavolej `append` pro všechny kombinace barev a hodnot: ```python balicek = [] for barva in '♠', '♥', '♦', '♣': - for hodnota in list(range(2, 11)) + ['J', 'Q', 'K', 'A']: - balicek.append(str(hodnota) + barva) + for hodnota in ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']: + balicek.append(hodnota + barva) print(balicek) ``` +> [note] Jde to líp? +> Psát do programu výčet po sobě jdoucích čísel, +> `'2', '3', '4', '5', '6', '7', '8', '9', '10'`, +> není ideální – na takovou otročinu přece máme počítače! +> Zkus čísla dostat pomocí `range`. +> Ale pozor, není to úplně přímočaré: +> +> * Jaké argumenty dáš funkci `range`, abys dostal{{a}} čísla od 2 do 10? +> * Funkce `range` vrací sekvenci, která ale není seznam. +> Abys ji mohl{{a}} spojit se seznamem `['J', 'Q', 'K', 'A']`, budeš ji muset +> na seznam převést: `list(range(...))` +> * Abys mohl{{a}} čísla z `range` připojit k řetězci jako `♠`, budeš muset +> každou hodnotu před použitím převést na řetězec: `str(hodnota)`. +> +> Bonus: Jaký je nejkratší zápis, kterým můžeš zadat seznam +> `['J', 'Q', 'K', 'A']`? +> +> Řešení najdeš v textu o kousek níže. + + ## Seznamy a řetězce Seznamy a řetězce jsou druhy *sekvencí*. @@ -458,9 +478,12 @@ Seznam změní „na místě“ a nic nevrací (podobně jako metoda `sort`). ```python import random +ciselne_hodnoty = list(range(2, 11)) +pismenne_hodnoty = list('JQKA') + balicek = [] for barva in '♠', '♥', '♦', '♣': - for hodnota in list(range(2, 11)) + ['J', 'Q', 'K', 'A']: + for hodnota in ciselne_hodnoty + pismenne_hodnoty: balicek.append(str(hodnota) + barva) print(balicek) From 9d5b66dc8f8ab84da97651cbffc4c29f81a50015 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 17 Aug 2020 14:37:53 +0200 Subject: [PATCH 17/17] Clarify description of `pop()` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > „vrátí“ [vyzní] víc jako „vrátí zpátky do seznamu“ než jako „return“ Co-authored-by: Glutexo --- lessons/beginners/list/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lessons/beginners/list/index.md b/lessons/beginners/list/index.md index 57b5acca1d..06345f6f0c 100644 --- a/lessons/beginners/list/index.md +++ b/lessons/beginners/list/index.md @@ -143,7 +143,7 @@ Všechny udělají změny přímo v daném seznamu a (kromě `pop`) vrací `Non * `extend()` přidá více prvků najednou, * `insert()` přidá prvek na danou pozici, -* `pop()` odebere *a vrátí* poslední prvek, +* `pop()` odebere poslední prvek a *vrátí ho* (jako návratovou hodnotu), * `remove()` odstraní první výskyt daného prvku, * `sort()` seznam seřadí (řetězce podle “abecedy”, čísla vzestupně), * `reverse()` obrátí pořadí prvků,