Seznamy (typ 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.

Položky Pythonovského seznamu mohou být různých typů.

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.

Indexování

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.

Pokud použijeme záporný index, berou se znaky z konce seznamu. Např. na indexu -1 je tedy string "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.

Změna položky

Narozdíl od znakových řetězců můžeme jednotlivé položky seznamu měnit.

Slicing

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

Vícerozměrné seznamy

Položkami seznamu mohou být opět i seznamy.

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

Indexování vícerozměrných seznamů

V seznamu seznam je vnořený seznam na indexu 4.

Pokud chceme získat první prvek vnořeného seznamu, který je na indexu 0, píšeme tedy

Operace se seznamy

Sčítání

Seznamy můžeme sčítat pomocí operátoru +.

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.

Pokud chceme sčítat seznam s jiným typem než se seznamem, Python ohlásí TypeError.

Násobení seznamů

Seznamy je možné násobit pomocí operátoru *, podobně jako znakové řetězce.

Přidání prvku do seznamu

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.

Někdy potřebujeme na začátku prázdný seznam. Prázdný seznam neobsahuje žádné prvky, stačí tedy napsat prázdné hranaté závorky.

Odebrání prvku ze seznamu

Pomocí pop můžeme odebrat prvek z konce seznamu. Původní seznam se změní - je v něm o prvek méně.

Odebraný prvek si navíc můžeme uložit do proměnné a dále s ním pracovat.

Pomocí pop můžeme odebírat také prvky ze začátku seznamu.

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

Kopírování seznamu

Pokud přiřadíme seznam do nové proměnné

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ý.

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.

Další operace se seznamy

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.

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.

Operátor 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.

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ě".)

Příklad

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?

Procházení prvků seznamu pomocí while

while cyklem do délky seznamu:

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.

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:

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.

Pokud zadáme range dva parametry, zadáváme rozah <od, do)

Třetí parametr, pokud je zadaný, určuje krok - další vygenerované číslo může být např. vždy o 2 větší.

Vypsání všech prvků seznamu

Pythonovský technický tvar

Pomocí nějakého cyklu

Nad podobou výpisu tak máme plnou kontrolu.

Pomocí print s *

Hvězdička "rozbalí" seznam - je to jako kdybychom dali printu více proměnných, které se mají vytisknout.