list
)¶Pokud chceme pracovat s posloupností dat, hodí se nám uložit všechny položky do jedné proměnné.
V Pythonu k tomu slouží seznam (typ list
).
Seznam se hodí třeba tehdy, pokud chceme uložit více čísel... abychom je potom mohli např. seřadit od nejmenšího po největší.
Seznam se zapisuje do hranatých závorek [ ]
, jednotlivé položky jsou odděleny čárkami.
cisla = [7, 5, 13, 1000, 2, -8]
Položky Pythonovského seznamu mohou být různých typů.
vsehochut = [1.5, 80, "jelen", True, "a"]
Poznámka: Hodně věcí bude stejných, jako když jsme pracovali se znakovými řetězci, které jsou v Pythonu posloupnost jednotlivých znaků. Např. délku seznamu, tj. počet jeho prvků, můžeme zjistit pomocí len
.
len(vsehochut)
5
Indexování funguje pro seznamy stejně jako pro znakové řetězce.
K jednotlivým položkám seznamu, je možné přistupovat pomocí jejich indexu zapsaného v hranatých závorkách. Čísluje se, tak jako vždy v Pythonu, od nuly.
0 1 2 3 4
vsehochut = [1.5, 80, "jelen", True, "a"]
Například "jelen" je na indexu 2.
vsehochut[2]
'jelen'
Pokud použijeme záporný index, berou se znaky z konce seznamu. Např. na indexu -1 je tedy string "a"
.
vsehochut[-1]
'a'
Pokud se dostaneme mimo rozsah řetězce, dojde k chybě IndexError: list index out of range
.
_Poznámka:_V ReCodExu se tato chyba projeví jako Lookup Error
.
vsehochut[5]
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_8628/31034509.py in <module> ----> 1 vsehochut[5] IndexError: list index out of range
Narozdíl od znakových řetězců můžeme jednotlivé položky seznamu měnit.
cisla[0] = "sedmicka"
cisla
['sedmicka', 5, 13, 1000, 2, -8]
Při práci se seznamy je možné používat slicing stejně jako u znakových řetězců. Čísluje se opět od nuly. Vypíšou se prvky z intervalu <dolni_mez; horni_mez)
.
cisla[2:4]
[13, 1000]
Položkami seznamu mohou být opět i seznamy.
seznam = [1.5, 80, "jelen", True, ["vnořený", "seznam"], "a"]
Vnořováním seznamů je možné vytvářet vícerozměrné struktury.
(Uvnitř hranatých závorek můžeme libovolně odřádkovávat.)
matice = [
[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 5, 0],
[0, 0, 0, 3]
]
V seznamu seznam
je vnořený seznam na indexu 4.
seznam[4]
['vnořený', 'seznam']
Pokud chceme získat první prvek vnořeného seznamu, který je na indexu 0, píšeme tedy
seznam[4][0]
'vnořený'
s1 = [1, 2, 3]
s2 = ["a", "b", "c"]
s1 + s2
[1, 2, 3, 'a', 'b', 'c']
Je možné sčítat pouze seznam se seznamem. Pokud tedy chceme například do existujícího seznamu s1
přidat další prvek s hodnotou 4, musíme přičíst jednoprvkový seznam.
s1 + [4]
[1, 2, 3, 4]
Pokud chceme sčítat seznam s jiným typem než se seznamem, Python ohlásí TypeError
.
s1 + 4
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_36600/700021152.py in <module> ----> 1 s1 + 4 TypeError: can only concatenate list (not "int") to list
Seznamy je možné násobit pomocí operátoru *, podobně jako znakové řetězce.
pozitivni = [True]*10
pozitivni
[True, True, True, True, True, True, True, True, True, True]
Pomocí append
můžeme přidat nový prvek na konec seznamu. Původní seznam se změní - je v něm o prvek navíc.
append
přidává vždy jen jeden prvek.
s = [1, 2]
s.append(5)
s
[1, 2, 5]
Někdy potřebujeme na začátku prázdný seznam. Prázdný seznam neobsahuje žádné prvky, stačí tedy napsat prázdné hranaté závorky.
s = []
s.append(10)
s.append(100)
s.append(1000)
s
[10, 100, 1000]
Pomocí pop
můžeme odebrat prvek z konce seznamu. Původní seznam se změní - je v něm o prvek méně.
s = [1, 2, 3, 4, 5]
s.pop()
s
[1, 2, 3, 4]
Odebraný prvek si navíc můžeme uložit do proměnné a dále s ním pracovat.
odebrany = s.pop()
print(odebrany)
print(s)
4 [1, 2, 3]
Pomocí pop
můžeme odebírat také prvky ze začátku seznamu.
s.pop(0)
s
[2, 3]
Místo nuly můžeme zadat jakýkoliv index ze seznamu.
Poznámka: Indexy prvků vždy začínají od 0 a vždy tvoří souvislou řadu. Pokud smažeme prvek z prostředka seznamu, prvky za tímto prvkem se posunou. (A to dá Pythonu práci.)
Pokud přiřadíme seznam do nové proměnné
s = ["akát", "bábrlinka", "cílovníci"]
novy_s = s
seznam s
se nezkopíruje, pouze seznamu ["akát", "bábrlinka", "cílovníci"]
přiřadíme nové pojmenování. Pokud kterýkoliv ze dvou seznamů - s
nebo novy_s
- změníme, změní se i ten druhý.
s[1] = "blýskavice"
print("s:", s)
print("novy_s:", novy_s)
s: ['akát', 'blýskavice', 'cílovníci'] novy_s: ['akát', 'blýskavice', 'cílovníci']
Pokud chceme opravdu kopii seznamu, tedy zkopírovat všechny prvky na jiné místo v paměti, a původní seznam nechat tak, jak je, můžeme použít např. copy
.
s = ["akát", "bábrlinka", "cílovníci"]
novy_s = s.copy()
s[1] = "blýskavice"
print("s:", s)
print("novy_s:", novy_s)
s: ['akát', 'blýskavice', 'cílovníci'] novy_s: ['akát', 'bábrlinka', 'cílovníci']
Python nám dává k dispozici další předpřipravené operace, které můžeme se seznamy provádět.
Kromě append
a pop
můžeme např. vyhledat první výskyt prvku určité hodnoty pomocí index
, pokud prvek v seznamu není, dojde k chybě. Nebo si můžeme prvky seznamu nechat seřadit od nejmenšího po největší pomocí sort
. reverse
otočí pořadí prvků v seznamu, seznam je potom pozpátku.
s = [12, 3, 5, 3, 18, 1]
s.index(3)
1
s.reverse()
s
[18, 12, 5, 3, 3, 1]
s.sort()
s
[1, 3, 3, 5, 12, 18]
Tyto operace můžete používat, je ale potřeba mít na paměti, že Pythonu jejich provedení nějaký čas zabere. Například index
musí v nejhorším případě projít všechny prvky seznamu, stejně, jako kdybychom prvek s nějakou hodnotou hledali "ručně" a v cyklu procházeli všechny prvky.
Pokud si nejste jisti tím, co daná operace pod povrchem přesně dělá, radila bych vám je spíše nepoužívat.
in
¶Operátor in
zjistí, jestli je prvek s danou hodnotou v seznamu. Pokud ano, je výsledek True
, pokud ne, výsledek je False
.
vsehochut = [1.5, 80, "jelen", True, "a"]
if "jelen" in vsehochut:
print("jelen tam je taky")
jelen tam je taky
Jak to funguje:
Python za nás projde celý seznam a porovnává jednotlivé jeho prvky. (A dá mu to stejnou práci, jako kdybychom to procházeli my "ručně".)
1. Na vstupu dostanete číslo k a potom posloupnost čísel, ukončenou -1, která do posloupnosti nepatří. Vypište ano, pokud číslo k je v posloupnosti, v opačném případě vypište ne.
2. Na vstupu dostanete posloupnost čísel, ukončenou -1, která do posloupnosti nepatří, a potom číslo k. Vypište ano, pokud číslo k je v posloupnosti, v opačném případě vypište ne.
V čem se liší 1. a 2.? Je potřeba čísla ukládat do paměti?
while
¶while
cyklem do délky seznamu:
vsehochut = [1.5, 80, "jelen", True, "a"]
i = 0
while i < len(vsehochut):
print(vsehochut[i])
i = i + 1
1.5 80 jelen True a
for
cyklus¶for
cyklus v Pythonu prochází prvky nějaké posloupnosti.
Pokud nám nezáleží na konkrétních indexech prvků posloupnosti a potřebujeme pouze projít její prvky, můžeme použít místo while
cyklu for
cyklus přes prvky seznamu.
for prvek in vsehochut:
print(prvek)
1.5 80 jelen True a
Jak to funguje:
Stejně jako u znakových řetězců.
for prvek in vsehochut:
"pro každý prvek v
[1.5, 80, "jelen", True, "a"]
proveď následující kód"
Python do proměnné prvek
dosadí nejprve první prvek seznamu vsehochut
, potom druhý a tak dále, dokud nedojde až na konec seznamu.
S proměnnou prvek
se dá uvnitř cyklu pracovat jako s jakoukoliv jinou proměnnou, tedy např. ji můžeme vypsat.
Jméno proměnné si můžete zvolit, jaké chcete. Já jsem zvolila jméno prvek
proto, aby byl kód pokud možno co nejlépe čitelný.
for
cyklus s range
¶for
cyklus v Pythonu vždy prochází nějakou sekvenci.
Pokud bychom chtěli např. vytisknout 10-krát slovo "ahoj", mohli bychom to udělat takto:
for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]:
print(i, "ahoj")
0 ahoj 1 ahoj 2 ahoj 3 ahoj 4 ahoj 5 ahoj 6 ahoj 7 ahoj 8 ahoj 9 ahoj
Pokud bychom chtěli vypsat 1000=krát "ahoj", mohli bychom...
A přesně k tomu je v Pythonu range
. Vygeneruje něco (objekt), co funguje jako seznam se zadaným počem prvků.
Pokud zadáme pouze jeden parametr n (n musí být celé číslo), budou to čísla z intervalu <0, n)
, tedy n už tam nebude.
for i in range(10):
print(i, "ahoj")
0 ahoj 1 ahoj 2 ahoj 3 ahoj 4 ahoj 5 ahoj 6 ahoj 7 ahoj 8 ahoj 9 ahoj
Pokud zadáme range
dva parametry, zadáváme rozah <od, do)
for i in range(1, 10):
print(i)
1 2 3 4 5 6 7 8 9
Třetí parametr, pokud je zadaný, určuje krok - další vygenerované číslo může být např. vždy o 2 větší.
for i in range(2, 20, 2):
print(i)
2 4 6 8 10 12 14 16 18
vsehochut = [1.5, 80, "jelen", True, "a"]
print(vsehochut)
[1.5, 80, 'jelen', True, 'a']
Nad podobou výpisu tak máme plnou kontrolu.
for i in range(len(vsehochut)):
print("index:", i, "hodnota:", vsehochut[i])
index: 0 hodnota: 1.5 index: 1 hodnota: 80 index: 2 hodnota: jelen index: 3 hodnota: True index: 4 hodnota: a
print
s *¶Hvězdička "rozbalí" seznam - je to jako kdybychom dali print
u více proměnných, které se mají vytisknout.
print(*vsehochut)
1.5 80 jelen True a