Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 11 - Seznam v Pythonu

V předešlém cvičení, Řešené úlohy k 9.-10. lekci Pythonu, jsme si procvičili nabyté zkušenosti z předchozích lekcí.

V dnešním Python tutoriálu si představíme seznam. Naučíme se ho vytvářet, procházet a pracovat s jeho položkami pomocí funkcí a metod.

Seznam

Představme si, že si chceme uložit nějaké údaje o více prvcích. Např. chceme v paměti uchovávat 10 čísel, políčka šachovnice nebo jména 50 uživatelů. Asi vám dojde, že v programování bude nějaká lepší cesta, než začít mechanicky vytvářet proměnné uzivatel1, uzivatel2, ... až uzivatel50. Nehledě na to, že jich můžeme potřebovat třeba 1000! A jak by se v tom potom hledalo? Brrr, takhle ne :)

Pokud potřebujeme uchovávat větší množství proměnných stejného typu, tento problém nám řeší seznam. Můžeme si ho představit jako řadu přihrádek, kde v každé máme uložený jeden prvek. Přihrádky jsou očíslované tzv. indexy, přičemž první má index 0:

Na obrázku je vidět pole osmi čísel - Základní konstrukce jazyka Python

(Na obrázku je vidět pole osmi čísel.)

Programovací jazyky se velmi liší v tom, jak se seznamem pracují. V některých jazycích (zejména starších, kompilovaných) nebylo možné za běhu programu vytvořit seznam s dynamickou velikostí (např. mu dát velikost dle nějaké proměnné). Seznam se musel deklarovat s konstantní velikostí přímo ve zdrojovém kódu. Toto se obcházelo tzv. pointery a vlastními datovými strukturami, což často vedlo k chybám při manuální správě paměti a nestabilitě programu (např. v C++). Tyto druhy seznamů se často označují jako pole. Jak víme, Python je interpretovaný programovací jazyk, takže neposkytuje pole s pevnou velikostí. Místo toho dostáváme dynamické seznamy, do kterých můžeme přidávat a odebírat položky podle libosti.

Výhody seznamu

Možná vás napadá, proč se tu zabýváme seznamy, když mají evidentně mnoho omezení a existují lepší datové struktury. Odpověď je prostá: seznamy jsou totiž jednoduché. Nemyslím pro nás na pochopení (to také), ale zejména pro Python. Rychle se s nimi pracuje, protože prvky jsou v paměti jednoduše uloženy za sebou. Navíc, díky dynamické povaze seznamů v Pythonu, nemusí všechny prvky zabírat stejně místa. Mnoho vestavěných funkcí a metod v Pythonu pracuje se seznamy nebo seznamy vrací. Je to klíčová datová struktura.

Pro hromadnou manipulaci s prvky seznamu se používají cykly.

Práce se seznamem

V následujících krocích si ukážeme, jak seznam deklarovat a naplnit jej vlastními daty.

Deklarace a inicializace seznamu

Seznam deklarujeme a inicializujeme pomocí hranatých závorek:

cisla = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Slovo cisla je samozřejmě název naší proměnné. Nyní tedy máme seznam deseti hodnot typu int v proměnné cisla.

Přístup k prvkům seznamu

K jednotlivým prvkům uloženým v seznamu přistupujeme prostřednictvím indexů uvnitř hranatých závorek, prvním indexem je vždy 0:

print(cisla[0])
cisla[5] = 50
print(cisla[5])

V konzoli uvidíme výstup:

Výstup seznamu:
1
50

Vytvoření seznamu pomocí range()

Plnit seznam ručně daty by bylo příliš pracné. Pojďme tedy zkusit využít nám již známé funkce range() a naplňme seznam hodnotami od 1 do 10. Protože ale range() nevrací seznam, nýbrž obecnou sekvenci, převedeme ji na seznam pomocí funkce list():

cisla = list(range(1,11))

K vytištění hodnot celého seznamu do konzole využijeme cyklu for (jako když jsme tiskli jednotlivé znaky řetězce):

cisla = list(range(1,11))

for cislo in cisla:
    print(cislo, end=" ")

Takto vypadá výstup v konzoli:

Výpis seznamu pomocí cyklu for:
1 2 3 4 5 6 7 8 9 10

V některých jazycích má cyklus for také variantu foreach (například v C#). V Pythonu se for cyklus používá pro iteraci přes prvky v kolekci, a je tedy ekvivalentem k foreach cyklu v jiných jazycích, jako je C#.

Mějme na paměti, že nejsme schopni pomocí cyklu for nijak editovat prvky v seznamu. V každé iteraci je v cyklu reference na neměnnou položku. Následující příklad tedy nebude fungovat:

# Tento kód je chybný
cisla= list(range(1, 11))
for cislo in cisla:
    cislo += 1
print(cisla)

Zápis cislo += 1 je zkrácená verze cislo = cislo + 1. V Pythonu se používá naprosto běžně ke zkrácení operací s proměnnými. Analogicky funguje i s ostatními operátory (např. -=, *=, /= atd.).

Výsledek bude stále:

Pokus o změnu v seznamu během cyklu for:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Funkce print(cisla) vytiskne obsah seznamu v hranatých závorkách.

Úprava obsahu seznamu s range()

V předchozím příkladu jsme totiž změnili pouze hodnoty proměnných v cyklu, nikoliv skutečného seznamu. Pakliže chceme upravit hodnoty seznamu v cyklu, musíme k nim přistoupit na základě jejich indexů:

for i in range(len(cisla)):
    cisla[i] += 1
print(cisla)

Funkce len() vrací počet prvků v seznamu.

Řetězcové seznamy

Při práci se seznamy nejsme limitováni jen používáním čísel. Založme si ručně seznam Simpsonů:

simpsons = ["Homer", "Marge", "Bart", "Lisa", "Maggie"]

K iteraci položek v seznamu můžeme kromě funkce range() použít také funkci enumerate(). Její výhodou je, že nám vrátí jak index položky, tak i položku samotnou:

for i, prvek in enumerate(simpsons):
    print(f"{i}: {prvek}")

Seznamy často slouží k ukládání mezivýsledků, které se potom dále v programu používají. Když něco potřebujeme 10x, tak to nebudeme 10x počítat, ale spočítáme to jednou a uložíme do seznamu, odkud poté výsledek jen načteme.

Ořezávání

V Pythonu je možné dostat jen "ořezanou" část seznamu. Syntaxe je podobná jako v případě přístupu k položkám. Jen upřesníme více argumentů, podobně jako u funkce range():

cisla = range(10)
print(list(cisla))
print(list(cisla[0:5]))
print(list(cisla[2:8]))
print(list(cisla[1:7:2]))
print(list(cisla[2:9:2]))
print(list(cisla[6:]))

Varianty argumentů jsou:

  • nazev_seznamu[m] vybere jediný prvek,
  • nazev_seznamu[m:n] vybere prvky v rozsahu mn-1 (prvek n už zahrnutý není),
  • nazev_seznamu[m:n:i] vybere m a každý i-tý prvek do n-1.

Jednotlivé argumenty určující co chceme vybrat lze i vynechat. Můžeme tedy napsat [::2], což nám vybere každý druhý prvek v seznamu.

Pokud není zadaný první prvek, bere se od začátku seznamu (index 0) . Není-li zadaný druhý prvek, bere se konec seznamu. A není-li zadáno, o kolik prvků chceme postupovat, je výchozí 1, tudíž se vezme každý prvek v zadaném intervalu.

Metody a funkce pro práci se seznamy

Základní operace se seznamy v Pythonu jsme si již představili. Teď se zaměříme na prohloubení našich dovedností s využitím různých metod a funkcí, které Python pro efektivní a flexibilní manipulaci se seznamy nabízí. Umožňují nám provádět operace jako třídění, invertování, přidávání nebo odstraňování prvků a mnoho dalšího. S těmito nástroji se stává práce se seznamy v Pythonu mnohem jednodušší a intuitivnější.

Metody pro práci se seznamy

Existuje mnoho metod určených přímo pro práci se seznamy. Pojďme se podívat na ty nejpoužívanější. Jednotlivé metody si představíme postupně a uvedeme si také jednoduché příklady.

Metoda append()

Metoda append() vloží novou položku na konec seznamu:

cisla = [2, 3, 16, 21]
cisla.append(13)
print(cisla)

Metoda insert()

Metoda insert() vloží novou položku na konkrétní index v seznamu. První parametr metody je index, na který chceme vložit novou položku, a druhý parametr je samotná položka:

cisla = [2, 3, 16, 21]
cisla.insert(1, 10)
print(cisla)

Metoda extend()

Metoda extend() připojí všechny položky z dané sekvence do seznamu:

cisla = [2, 3, 16, 21]
dalsi_cisla = [13, 18, 24]
cisla.extend(dalsi_cisla)
print(cisla)

Metoda clear()

Metoda clear() odebere všechny položky ze seznamu. Stejného výsledku můžeme dosáhnout zápisem del seznam[:]:

cisla = [2, 3, 16, 21]
cisla.clear()
print(cisla)

Metoda remove()

Metoda remove() odebere danou položku ze seznamu. Tato funkce vyvolá výjimku v případě, že hledaná položka není v seznamu nalezena:

cisla = [2, 3, 16, 21]
cisla.remove(3)
print(cisla)

Metoda reverse()

Metoda reverse() otočí pořadí položek v seznamu tak, že první položka je nyní poslední, druhá je předposlední, atd:

cisla = [2, 3, 16, 21]
cisla.reverse()
print(cisla)

Metoda count()

Metoda count() vrací počet výskytů dané položky v seznamu:

cisla = [2, 3, 16, 21, 2, 2, 3]
pocet_dvojek = cisla.count(2)
print(pocet_dvojek)

Metoda sort()

Metoda sort() seznam seřadí. Je dokonce tak chytrá, že pracuje podle toho, co máme v seznamu uložené. Textové řetězce třídí podle abecedy, čísla podle velikosti, atd. Zkusme si setřídit a vypsat naši rodinku Simpsonů:

simpsons = ["Homer", "Marge", "Bart", "Lisa", "Maggie"]
simpsons.sort()
for s in simpsons:
    print(s, end = " ")

Metoda index()

Metoda index() vrací index prvního výskytu hledané položky. Pokud položka není nalezena, vyvolá výjimku ValueError. Metoda si bere hledanou položku jako parametr. Dále můžeme upřesnit dva další číselné parametry, určující počáteční a konečný index, mezi kterými má být položka hledána. Umožníme například uživateli zadat jméno Simpsona a řekneme mu, na jaké pozici je uložený. Teď to pro nás nemá hlubší význam, protože položka jen jednoduchý string. Bude se nám to však velmi hodit ve chvíli, kdy v seznamu budeme mít uloženy plnohodnotné objekty. Berme to tedy jako takovou přípravu:

simpsons = ["Homer", "Marge", "Bart", "Lisa", "Maggie"]
simpson = input("Ahoj, zadej svého oblíbeného Simpsona (z rodiny Simpsonů): ")
if simpson in simpsons:
    pozice = simpsons.index(simpson);
    print(f"Jo, to je můj {pozice+1}. nejoblíbenější Simpson!")
else:
    print("Hele, tohle není Simpson!")

A v konzoli vidíme:

Využití metody index():
Ahoj, zadej svého oblíbeného Simpsona (z rodiny Simpsonů): 
Bart
Jo, to je můj 3. nejoblíbenější Simpson!

Funkce pro práci se seznamy

Python také obsahuje několik globálních funkcí pro práci se seznamem. Tyto funkce nejsou specifické pouze pro seznamy, ale fungují také na jiných kolekcích nebo sekvencích, jako jsou n-tice, řetězce, množiny a slovníky.

Funkce len()

S touto funkcí jsme se již setkali. Vrací nám počet všech položek v seznamu:

cisla = [2, 3, 16, 21, 2, 2, 3]
pocet_prvku = len(cisla)
print(pocet_prvku)

Funkce min(), max(), sum()

Jedná se o matematické funkce:

  • min() vrací nejmenší z položek v seznamu,
  • max() vrací největší z položek v seznamu,
  • sum() vrací součet všech hodnot položek v seznamu (u číselných typů).

Podívejme se na příklad:

cisla = [5, 10, 15, 20, 25]

nejmensi = min(cisla)
print(f"Nejmenší číslo v seznamu je: {nejmensi}")

nejvetsi = max(cisla)
print(f"Největší číslo v seznamu je: {nejvetsi}")

soucet = sum(cisla)
print(f"Součet všech čísel v seznamu je: {soucet}")

Funkce sorted()

Tato funkce nápadně připomíná metodu sort(), ale na rozdíl od ní vrací setříděnou kopii původního seznamu, aniž by jej jakkoliv ovlivnila:

cisla = [2, 8, 1, 5, 3]
setridena_cisla = sorted(cisla)
print(f"Neuspořádaná čísla: {cisla}")
print(f"Setříděná čísla: {setridena_cisla}")

Homogennost seznamů v Pythonu

Zatímco v jiných programovacích jazycích bývají seznamy omezeny na uchovávání prvků jednoho datového typu, Python nám dovoluje vytvářet seznamy, které obsahují různé datové typy. Například:

smes = [1, "Ahoj", 3.14, [1, 2, 3]]

Seznam smes obsahuje celé číslo, řetězec, desetinné číslo a jiný seznam. Takové seznamy jsou považovány za nehomogenní. Ačkoli jsou nehomogenní seznamy v některých situacích užitečné, často také působí komplikace. Například pokud se pokusíme použít některé funkce, které vyžadují homogenní seznam (např. funkce určené pro práci pouze s čísly), narazíme na chyby. Když se chytáme třeba sečíst všechny prvky v seznamu, musíme se ujistit, že všechny prvky v seznamu jsou čísla.

Vždy je nutné ujistit se, že všechny prvky v seznamu jsou kompatibilní s operacemi, které se seznamem budeme provádět.

Tak, a to už by pro dnešek stačilo. Můžete si se seznamem hrát a experimentovat 😉

V následujícím kvízu, Kvíz - Cykly a seznamy v Pythonu, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.


 

Předchozí článek
Řešené úlohy k 9.-10. lekci Pythonu
Všechny články v sekci
Základní konstrukce jazyka Python
Přeskočit článek
(nedoporučujeme)
Kvíz - Cykly a seznamy v Pythonu
Článek pro vás napsal gcx11
Avatar
Uživatelské hodnocení:
769 hlasů
(^_^)
Aktivity