Funkce range(10)
vrátí speciální hodnotu,
která v sobě obsahuje čísla od 0 do 9:
>>> 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:
>>> 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:
>>> range(10000)
range(0, 10000)
>>> list(range(10000))
[0, 1, 2, 3, ..., 9999]
Kdybys zkusila třeba list(range(1000000000000000))
, počítači
dojde paměť.
Biliarda čísel se tam prostě nevejde.
Python vyhodí výjimku MemoryError
.
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.
Spousta operací, které znáš od seznamů, bude fungovat i s range
:
>>> 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
>>> import random
>>> random.choice(zajimava_cisla)
1229
>>> 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 – mazání prvků nebo metody jako
zajimava_cisla.sort()
, zajimava_cisla.pop()
fungovat nebudou.
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:
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.