Sekvenční datové typy

Doposud jsme se zabývali pouze jednoduchými datovými typy, které neumožňovaly pracovat s celou skupinou hodnot. Často však potřebujeme pracovat právě s takovými skupinami navzájem souvisejících údajů. K tomu právě slouží sekvenční datové typy.

Sekvenční datové typy jsou uspořádané, indexované, polím podobné kolekce, které se vyskytují jak v konstantní tak proměnlivé formě. Mezi nekonstantní sekvenční datové typy patří seznamy. Konstantní sekveční datové typy se nazývají tuple (n-tice).

Seznamy (Lists)

Seznam je objekt reprezentující nekonstantní, sekvenční, heterogenní kolekci objektů. Podívejme se podrobněji na významy jednotlivých slov v definici:

Kolekce

V Jythonu seznam může obsahovat odkazy na skupinu objektů.

Heterogenní

V Jythonu nemusí seznam obsahovat položky stejného datového typu. V jednom seznamu můžeme současně shromažďovat základní datové typy, objekty uživatelem definovaných tříd, další seznamy, tuple nebo asociativní pole (hashe).

Sekvenční

Jednotlivé prvky v seznamu jsou dosažitelné prostřednictvím celočíselných indexů. První prvek seznamu má index 0, poslední prvek seznamu má index roven počet_prvků - 1.

Nekonstantní

Obsah seznamu není konstantní. Může se během vykonávání kódu měnit. Můžeme do seznamu prvky dynamicky přidávat, odebírat, popřípadě i jednotlivé prvky měnit. To vše bez toho, že bychom vytvářeli nový objekt reprezentující obsah seznamu. Velikost, počet prvků, seznamu se může časem měnit.

Seznam můžeme vytvořit tak, že vyjmenujeme jednotlivé položky seznamu, navzájem oddělené čárkou, a celý seznam uzavřeme do hranatých závorek:

[výraz, výraz, ....]

Prázdný seznam je reprezentován prázdnými hranatými závorkami [] .

>>> slovo = 'Popokatepetl'
>>> seznam = [1, 123, slovo, [], 'ahoj']
>>>
>>> seznam
[1, 123, 'Popokatepetl', [], 'ahoj']
>>>
>>> jinySeznam = [123, seznam, 'Jirka']
>>>
>>> jinySeznam
[123, [1, 123, 'Popokatepetl', [], 'ahoj'], 'Jirka']
>>>
>>> zasobnik = [] #prazdny seznam
>>> zasobnik
[]

Indexování a výřezy

Seznamy lze, obdobně jako řetězce, indexovat a vytvářet výřezy:

>>> seznam
[1, 123, 'Popokatepetl', [], 'ahoj']
>>>
>>> seznam[0] #Prvni prvek seznamu
1
>>> seznam[-1] #Posledni prvek seznamu
'ahoj'
>>> seznam[:2] #Prvni dva prvky seznamu
[1, 123]
>>> seznam[-2:] #Posledni dva prvky seznamu
[[], 'ahoj']
>>>
>>> len(seznam) #Pocet prvku v seznamu
5

Za pozornost stojí následující výraz seznam[:], který ze seznamu vytvoří novou, tzv. mělkou (anglicky shallow copy) kopii, tj. nový objekt mající stejný obsah jako původní seznam.

>>> seznam = [123, 'Eva', 'Ona jedna']
>>> seznam
[123, 'Eva', 'Tomas']
>>>
>>> kopie = seznam[:] #Vytvorim kopii seznamu
>>> kopie
[123, 'Eva', 'Tomas']

Skutečně jedná o kopii seznamu, lze to vidět v následujícím výpisu:

>>> seznam[0] = 'Monika'     #Zmenim hodnotu 1. prvku
>>> seznam
['Monika', 'Eva', 'Tomas']
>>> kopie #Zde ke zmene nedoslo
[123, 'Eva', 'Tomas']

Že se jedná o mělkou kopii, je patrné z následujícího výpisu:

>>> seznam = [[1], [2], [3]]
>>> kopie = seznam[:]
>>> kopie
[[1], [2], [3]]
>>>
>>> seznam[0][0] = 111
>>> seznam
[[111], [2], [3]]
>>> kopie
[[111], [2], [3]]

Při změně obsahu objektu vnořeného do seznamu seznam se tato změna projeví i v kopii seznamu kopie.

Oproti tomu přiřazení seznam2 = seznam přiřadí proměnné seznam2 pouze odkaz na stávající objekt původního seznamu:

>>> 
>>> jinySeznam = seznam
>>>
>>> seznam
[123, 'Eva', 'Tomas']
>>> jinySeznam
[123, 'Eva', 'Tomas']
>>>
>>> seznam[0] = 'Monika'
>>> seznam
['Monika', 'Eva', 'Tomas']
>>> jinySeznam
['Monika', 'Eva', 'Tomas']

Hodnota seznamu je skutečně pouze reference na objekt. Obdobně jako v Javě, je možné tyto odkazy uchovávat na více místech, ve více proměnných, ale stále se bude jednat o tentýž objekt, tentýž seznam. Následující příklad to krásně demonstruje:

>>> klec = []
>>> kamery = [klec] * 4 #Jedna klec, 4 kamery
>>>
>>> kamery
[[], [], [], []]
>>> klec.append('kocka') #Vloz kocku do klece
>>>
>>> kamery
[['kocka'], ['kocka'], ['kocka'], ['kocka']]

Získali jsme 4 různé pohledy na tu samou kočku v jedné kleci.

Při vnořování seznamů platí pro indexaci pravidla patrná z příkladu:

>>> radek1 = [11,12,13]
>>> radek2 = [21,22]
>>> matice = [radek1, radek2]
>>>
>>> matice
[[11, 12, 13], [21, 22]]
>>> matice[0][2] #Prvni radek, treti prvek
13
>>> matice[1][1] #Druhy radek, druhy prvek
22

Přiřazovat hodnoty je možné nejen jednotlivým prvkům seznamu, ale i výřezům:

>>> zasobnik = ['a', 'b', 'c', 'd', 'e']
>>> zasobnik[0] = 'ahoj'
>>>
>>> zasobnik
['ahoj', 'b', 'c', 'd', 'e']
>>>
>>> zasobnik[3:4] = ['konec']
>>>
>>> zasobnik
['ahoj', 'b', 'c', 'konec', 'e']
>>>

ale pozor:

>>> zasobnik = [0,1,2,3]
>>> zasobnik[2:3] = 'abcde'
>>>
>>> zasobnik
[0, 1, 'a', 'b', 'c', 'd', 'e', 3]

Na seznamy je možné též aplikovat operátory "*" (hvězdička) a " + " (plus):

>>> s1 = ['a', 'b', 'c']
>>> s2 = [1, 2, 3]
>>>
>>> s1 + s2
['a', 'b', 'c', 1, 2, 3]
>>>
>>> s1 * 2
['a', 'b', 'c', 'a', 'b', 'c']

Test, zda prvek x je členem seznamu s je možné provést pomocí operátoru in :

>>> s = ['jedna', 2, 'tre', 'yottsu']
>>>
>>> x = 'tre'
>>>
>>> x in s
1
>>>
>>> 'ctyri' in s
0