|
| 1 | +# Range – sekvence čísel |
| 2 | + |
| 3 | +Funkce `range(10)` vrátí speciální hodnotu, |
| 4 | +která v sobě obsahuje čísla od 0 do 9: |
| 5 | + |
| 6 | +```pycon |
| 7 | +>>> sekvence = range(10) |
| 8 | +>>> sekvence |
| 9 | +range(0, 10) |
| 10 | +``` |
| 11 | + |
| 12 | +Je to hodnota typu `range`, podobně jako čísla jsou typu `int`, řetězce typu |
| 13 | +`str`, nebo seznamy typu `list`. |
| 14 | + |
| 15 | +Chceš-li se podívat, co v tomhle `range(0, 10)` vlastně je, máš dvě základní |
| 16 | +možnosti – projít ho cyklem `for` nebo převést na seznam konkrétních čísel: |
| 17 | + |
| 18 | +```pycon |
| 19 | +>>> sekvence |
| 20 | +range(0, 10) |
| 21 | +>>> for i in sekvence: |
| 22 | +... print(i) |
| 23 | +0 |
| 24 | +1 |
| 25 | +2 |
| 26 | +3 |
| 27 | +4 |
| 28 | +5 |
| 29 | +6 |
| 30 | +7 |
| 31 | +8 |
| 32 | +9 |
| 33 | +>>> list(sekvence) |
| 34 | +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
| 35 | +``` |
| 36 | + |
| 37 | +Možná se ptáš – proč tak složitě? |
| 38 | +Proč se místo `range(0, 10)` prostě ta čísla neukážou rovnou? |
| 39 | + |
| 40 | +Je to proto, že `range` se dá použít na opravdu dlouhé řady čísel: |
| 41 | + |
| 42 | +```pycon |
| 43 | +>>> range(10000) |
| 44 | +range(0, 10000) |
| 45 | +>>> list(range(10000)) |
| 46 | +[0, 1, 2, 3, ..., 9999] |
| 47 | +``` |
| 48 | + |
| 49 | +Kdybys zkusil{{a}} třeba `list(range(1000000000000000))`, počítači |
| 50 | +dojde paměť. |
| 51 | +Biliarda čísel se tam prostě nevejde. |
| 52 | +Python vyhodí výjimku `MemoryError`. |
| 53 | + |
| 54 | + |
| 55 | +> [warning] |
| 56 | +> Pokud máš na počítači v jiném okně neuloženou práci, radši `list(range(...))` |
| 57 | +> s hodně vysokými čísly nezkoušej. |
| 58 | +> |
| 59 | +> U absurdně vysokého čísla jako `1000000000000000` Python předem ví, |
| 60 | +> že mu paměť dojde, a tak ohlásí chybu ještě než se bude snažit seznam vytvořit. |
| 61 | +> U trochu menšího čísla (např. `1000000000`, ale na každém počítači je to |
| 62 | +> jinak) se může stát, že se Python pokusí seznam začít tvořit, zaplní přitom |
| 63 | +> většinu dostupné paměti a počítač „zamrzne“. |
| 64 | +> V závislosti na systému se pak třeba může stát že reakce na |
| 65 | +> <kbd>Ctrl</kbd>+<kbd>C</kbd> bude trvat hodně dlouho. |
| 66 | +
|
| 67 | +Se samotným `range(1000000000000000)` ale není problém. |
| 68 | +S konceptem *všech čísel od 0 do biliardy* se počítač vypořádá, i když si je |
| 69 | +neumí „zapamatovat“ všechny *najednou*. |
| 70 | + |
| 71 | +Je spousta věcí, které Python umí s `range` udělat, aniž by potřeboval |
| 72 | +„spočítat“ každé z čísel. |
| 73 | +Spousta operací, které znáš od seznamů, bude fungovat i s `range`: |
| 74 | + |
| 75 | +```pycon |
| 76 | +>>> zajimava_cisla = range(8, 10000, 3) # Každé třetí číslo od 8 do 9999 |
| 77 | +>>> zajimava_cisla[80] # Osmdesáté "zajímavé číslo" |
| 78 | +248 |
| 79 | +>>> zajimava_cisla[:5] # Prvních 5 "zajímavých čísel" |
| 80 | +range(8, 23, 3) |
| 81 | +>>> list(zajimava_cisla[:5]) # Vypsání prvních 5 "zajímavých čísel" |
| 82 | +[8, 11, 14, 17, 20] |
| 83 | +>>> len(zajimava_cisla) # Kolik tam je čísel? |
| 84 | +3331 |
| 85 | +>>> 1337 in zajimava_cisla # Je v této sekvenci moje konkrétní číslo ? |
| 86 | +True |
| 87 | +>>> zajimava_cisla.index(1337) # Kolikáté je? |
| 88 | +443 |
| 89 | +``` |
| 90 | + |
| 91 | +```pycon |
| 92 | +>>> import random |
| 93 | +>>> random.choice(zajimava_cisla) |
| 94 | +1229 |
| 95 | +``` |
| 96 | + |
| 97 | +```pycon |
| 98 | +>>> for i in zajimava_cisla: |
| 99 | +... print(i) |
| 100 | +... if i > 20: |
| 101 | +... break # Stačilo! |
| 102 | +8 |
| 103 | +11 |
| 104 | +14 |
| 105 | +17 |
| 106 | +20 |
| 107 | +23 |
| 108 | +``` |
| 109 | + |
| 110 | +Objekt `range` ale nejde měnit – mazání prvků nebo metody jako |
| 111 | +`zajimava_cisla.sort()`, `zajimava_cisla.pop()` fungovat nebudou. |
| 112 | + |
| 113 | +> [note] Proč ne? |
| 114 | +> Když máš objekt jako `range(8, 10000, 3)`, osmdesátý prvek je jen trocha |
| 115 | +> matematiky: spočítáš `8 + 3 * 80` a zkontroluješ že to nepřesáhlo `10000`. |
| 116 | +> Podobně je to s ostatními sekvencemi „všech <var>X</var>-tých čísel od |
| 117 | +> <var>A</var> do <var>B</var>“, tedy s ostatními `range`. |
| 118 | +> |
| 119 | +> Kdyby ale šlo udělat něco jako: |
| 120 | +> |
| 121 | +> ```python |
| 122 | +> sekvence = range(8, 10000, 3) |
| 123 | +> del sekvence[10] |
| 124 | +> sekvence.insert(103, 'ježek') |
| 125 | +> ``` |
| 126 | +> |
| 127 | +> … jde najednou o mnohem složitější koncept, kde se N-tý prvek hledá mnohem |
| 128 | +> hůř. Už to není jednoduchá sekvence čísel – už to není `range`, ale spíš |
| 129 | +> seznam jakýchkoli hodnot. |
| 130 | +
|
| 131 | +Pokud budeš něco, co `range` neumí, potřebovat, převeď `range` na seznam. |
0 commit comments