Vlastnosti datových typů
V této kapitole je popsáno, jak se pracuje se základními typy Pythonu. Je to megadlouhá kapitola, tak se na to připravte.
None
Tento typ se používá v případě, že nechcete mít v proměnné žádnou
hodnotu. V jazyce C odpovídá tomuto typu hodnota NULL
. None má tu
výhodu, že se rovná jen sám sobě (nerovná se ani nule!). Hodnotu
None vrací funkce, které nic nevrací. Nepleťte si None a
'None' - to druhé je typ string!
Využít se dá při psaní funkce, která v případě, že parametry funkce neumožní správný výpočet (například dělení nulou) vrátí hodnotu None, jinak číselný výsledek (který může být právě nula). Jednoduchou kontrolou, zda je vrácená hodnota rovna None zjistíte, zda se výpočet povedl.
True
>>> None == 0
False
Celé, celé dlouhé, racionální a komplexní číslo
Pro tyto typy existují standardní operátory + (plus), - (mínus), * (krát), / (děleno), // (celočíselné dělení), % (zbytek po celočíselném dělení), () (závorky), a ještě operátor ** (mocnina). Na jejich používání není nic zvláštního.
1
>>> 3.0**(4/2)
9.0
>>> x = 3.0**4/2
>>> print(x)
40.5
Bitové operátory
Dále jsou v Pythonu binární operátory >>, << (bitové posuvy), ~ (vlnovka = binární komplement), | (bitové or), & (bitové and), ^ (stříška = bitové xor). Tyto operátory pracují jen s celými čísly.
>>> ~x # (vlnovka = binární doplněk/komplement)
-1
>>> x = 1
>>> x << 1
2
>>> x = 1
>>> x << 2
4
Seznamy
Seznam (anglicky list) je uspořádané zobrazení (tj. máte zaručeno, že v jakém pořadí do něj něco uložíte, v takovém to tam zůstane), které může obsahovat jakékoliv jiné datové typy.
Uvozuje se hranatými závorkami a k jednotlivým položkám se přistupuje pomocí indexů, obdobně jako u řetězců.
>>>print(x[1])
ahoj
>>> print(x[1:])
['ahoj', None]
>>> print(x[:-1])
[3, 'ahoj']
Hlavní výhodou seznamu, oproti n-ticím (viz níže) je, že jej můžete měnit příkazem del, přiřazením, nebo pomocí vlastních metod.
Seznam lze násobit podobně jako řetězce nebo n-tice (viz níže).
- >>> x= 3*x
- >>> print(x)
- [3, 'ahoj', None, 3, 'ahoj', None, 3, 'ahoj', None]
- >>> del x[3:6] # smaže prostřední trojici
- >>> print(x)
- [3, 'ahoj', None, 3, 'ahoj', None]
- >>> x[3:] = ['1 hodnota misto tri'] # smaže vše za třetí položkou až do konce a vloží novou hodnotu
- >>> print(x)
- [3, 'ahoj', None, '1 hodnota misto tri']
Protože nejsou seznamy neměnné, můžete použít slice i na jejich modifikaci (viz v příkladu řádky 4 a 7).
Metody
Seznam má metody, což jsou funkce implementované uvnitř seznamu,
které pracují s objekty uloženými v seznamu. (Vlastně všechny objekty v Pythonu
mají nějaké metody).
Volají se přes tzv. tečkovou notaci. Tj. napíše se jméno proměnné typu seznam,
tečka a jméno metody s případnými parametry v závorkách.
Všimněte si, že u metod je nutné psát na konci závorky (), i když jim
nepředáváte žádný argument.
Některé metody seznamu:
append(x)
k seznamu připojí objekt x.count(x)
vrací počet položek v seznamu odpovídající x.index(x)
vrací nejmenší index odpovídající položce x, nebo vyvolá výjimku (výjimky probereme později).insert(i, x)
do seznamu na index i vloží objekt x (totéž co seznam[i:i] = x).reverse()
obrátí položky v seznamu.pop(i)
odebere i-tý prvek ze seznamu a vrátí jej jako svou návratovou hodnotu. Pokud i neuvedete, vrátí poslední prvek ze seznamu.sort()
tato metoda seznam setřídí.
>>> # Python od verze 3.0 neumožňuje porovnávat různé datové typy
>>> # Proto funkce sort vyhodí v Pythonu 3.0 výjimku TypeError
>>> x=3*[3, 'ahoj', None]
>>> x.sort()
>>> print(x)
[None, None, None, 3, 3, 3, 'ahoj', 'ahoj', 'ahoj']
>>> # Následující příklad funguje v Pythonu 3.0, protože seznam x
>>> # obsahuje jen hodnoty stejného typu (jen čísla)
>>> x = [3, 5, 1, 44, -7, 0]
>>> x.sort()
>>> x
[-7, 0, 1, 3, 5, 44]
dir([])
.
N-tice
N-tice (anglicky tuple) je podobná seznamu.
N-tice je však neměnitelná (immutable).
Uvozuje se kulatými závorkami. Chcete-li deklarovat n-tici s jedním prvkem, musíte uvést za prvek čárku, jinak by takový výraz byl vyhodnocen jako objekt v závorce a ne n-tice s jedním objektem!
>>> type(x)
<class 'tuple'>
>>> x = (1)
>>> type(x)
<class 'int'>
>>> x = (1,)
>>> type(x)
<class 'tuple'>
Pokud použijete několik výrazů oddělených od sebe čárkou, jsou automaticky vyhodnoceny Pythonem jako n-tice a podle toho se chovají (závorky kolem n-tice už nejsou potřeba).
>>> print(x[2])
ahoj
>>> print(a,c) # tisknu dvě proměnné
a 3
>>> print ((a,c)) # tisknu n-tici proměnných
('a', 3)
N-tice lze násobit podobně jako řetězce, nebo seznamy, ale nejde z nich nic mazat, nebo je měnit.
>>> x = 2*x
>>> x
(1, 2, 'ahoj', None, 3, 4, 1, 2, 'ahoj', None, 3, 4)
>>> x[1:3]
(2, 'ahoj')
>>> x[0] = 'takt o nevyjde'
Traceback (most recent call last):
File "<pyshell#158>", line 1, in <module>
x[0] = 'takt o nevyjde'
TypeError: 'tuple' object does not support item assignment
Asi si říkáte, proč má Python seznamy a n-tice, když jsou téměř to samé. Zakopaný pse je právě v té neměnnosti n-tice. Ta je vyžadována například pro klíče slovníků (viz dále). Takže n-tici můžete použít jako klíč slovníku, ale seznam ne.
K převodu mezi seznamem a n-ticí můžete využít funkce list()
a tuple()
.
[1, 2, 3]
>>> tuple([1,2,3])
(1, 2, 3)
Slovníky
Slovník (anglicky dict), někdy též nazývaný asociativní pole, je datová struktura, která se může indexovat jakýmikoliv hodnotamy libovolných neměnitelných typů (takže ne seznamem, ale n-ticí ano).
Slovník je uvozen špičatými závorkami {} a jednotlivé položky se deklarují ve tvaru
index : hodnota
. K jednotlivým hodnotám se
přistupuje přes indexy. Klíče a hodnoty nelze zaměňovat.
>>> x={"klic": "hodnota", "none": None}
>>> print(x["klic"])
hodnota
>>> print(x["hodnota"])
Traceback (most recent call last):
File "<stdin>", line 1, in ?
KeyError: hodnota
>>> x["novy_klic"] = "nova_hodnota"
>>> print(x)
{'klic': 'hodnota', 'novy_klic': 'nova_hodnota', 'none': None}
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'jack': 4098, 'guido': 4127}
Všimněte si, že hodnoty ve slovníku nejsou uspořádány podle toho, jak byli do slovníku vloženy. Slovník není uspořádaná množina, na pořadí hodnot ve slovníku se nemůžete nikdy spolehnout.
Klíče slovníku musí být neměnné objekty, takže např. seznam nemůže být kličem, ale n-tice ano.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> slovnik = {(0,1,2):'hodnota'}
>>> slovnik[(1,0,2)] ='druha hodnota'
>>> slovnik
{(0, 1, 2): 'hodnota', (1, 0, 2): 'druha hodnota'}
Metody
Některé metody slovníku:
keys()
vrátí všechny klíče ze slovníkuvalues()
vrátí všechny hodnoty ze slovníkuhas_key(x) vrací True, pokud je x klíčem ve slovníku, jinak False.
has_key
. Místo ní
můžete použít operátor in
.
>>> for i in x.keys():
print(i,end=" ")
jedna tři dva
>>> "two" in x # operátor in hledá klíče, ne hodnoty
False
>>> "dva" in x
True
Chcete-li odstranit z asociativního pole nějaký záznam, použijte
příkaz del
takto:
>>> x
{'jedna': 'one', 'tři': 'three'}
Set
Set je neuspořádaná množina unikátních hodnot. Set má také definované některé matematické operace s množinami
>>> ovoce.add('meloun')
>>> ovoce
set(['hruska', 'jablko', 'meloun'])
>>> ovoce.add('jablko') # jablko uz v setu je, proto se znova neprida
>>> ovoce
set(['hruska', 'jablko', 'meloun'])
>>> zelenina = set(['mrkev','celer','redkvicka','celer','celer'])
>>> zelenina
set(['mrkev', 'celer', 'redkvicka'])
>>> ovoceazelenina = ovoce | zelenina
>>> ovoceazelenina
set(['hruska', 'jablko', 'mrkev', 'meloun', 'redkvicka', 'celer'])
>>> ovoceazelenina - ovoce
set(['mrkev', 'celer', 'redkvicka'])
>>> ovoceazelenina & ovoce
set(['hruska', 'jablko', 'meloun'])
>>> ovoce ^ {'jablko','pomeranc'}
set(['hruska', 'meloun', 'pomeranc'])
Řetězce
Řetězce se zapisují pomocí jednoduchých nebo dvojitých uvozovek. Oboje je ekvivalentní. Pokud je řetězec uvozen dvojitými uvozovkami, pak je jednoduchá uvozovka chápána jako obyčejný znak a naopak (uvnitř řetězce se nemusí před uvozovkou používat zpětné lomítko \' resp. \").
<class 'str'>
>>> type('hello "world"')
<class 'str'>
>>> print("hello \"world\"")
hello "world"
Řetězec může být uvozen i 3 uvozovkami (dvojitými nebo jednoduchými). potom se za konec řetězce pokládá jen sekvence 3. uvozovek (apostrfů) a můžete řetězec psát i na několik řádek.
>>> print(x)
veta plna "uvozovek" a 'uvozovek'''
>>> x = '''Věta napsaná
na několika řádcích. Všiměte si, že na mezerách
na začátku řádek záleží!'''
>>> print(x)
Věta napsaná
na několika řádcích. Všiměte si, že na mezerách
na začátku řádek záleží!
V řetězcích je možné používat speciální znaky podobně jako v jazyce C. Například \n znamená další řádek, \\ se píše místo zpětného lomítka, \' je uvozovka, \" je dvojitá uvozovka, \t tabulátor atd.
pozor na uvozovky '!'
>>>
Pokud nechcete aby se speciální znaky interprtovali, napište na začátek řetězce znak r (bez mezery).
pozor na uvozovky\t\'!\'\n\n\n
Řetězce lze sčítat a násobit. Pokud zasebe napíšete dva řetězcové literály, pak se spojí v jeden. Ale musí to být fakt řetězcové literály, pokud takhle zapíšete např. literál a funkci, která vrací řetězec, nebo proměnnou tak to nefunguje.
>>> x = x + " " + x
>>> print(x)
abc abc
>>> 5 * "X"
'XXXXX'
>>> print("hello" " " "world")
hello world
>>> print("hello " x)
File "<stdin>", line 1
print("hello " x)
^
SyntaxError: invalid syntax
Slice
Slice (česky řez, nebo taky kus, plátek …) je způsob, jak se dá označit část řetězce, seznamu nebo n-tice.
K jednotlivým položkám se dá přistupovat pomocí operátoru
[] (hranaté závorky), do kterých se píše index položky, kterou chcete
získat.
První znak má index 0, druhý 1 atd.
Poslední znak se dá indexovat číslem -1, předposlední -2 atd.
Slice také používá hranaté závorky, ale uvnitř není index, ale dvojtečkou oddělená dvojice indexů, která označuje začátek a konec rozsahu, který chceme získat.
Indexu před i za dvojtečkou se může ve slice vynechat, pak výběr začne od začátku, resp. pokračuje do konce. V extrémním případě, kdy se vynechají oba indexy, vybere se všechno.
>>> x[0]
'1'
>>> x[4]
'5'
>>> x[-1]
'5'
>>> x[0:2]
'12'
>>> x[2:]
'345'
>>> x[2:-2]
'3'
>>> x[1:-2]
23
>>> x[:]
'12345'
U slovníků, které jsou „mutable“, se dají slice využít k modifikaci vybrané části slovníku.
>>> x[1:3] = '1 až 3' # v tomto případě se bere text jako n-tice znaků
>>> x
[1, '1', ' ', 'a', 'ž', ' ', '3', 4, 5]
>>> del x[1:7]
>>> x
[1, 4, 5]
>>> x[2] = "Hello World"
>>> x
[1, 4, 'Hello World']
>>> x[1:1] = "Hello World", # díky čárce na konci je "Hello World" položka n-tice
>>> x
[1, 'Hello World', 4, 'Hello World']
Formátování
Python verze 3 zavedl nový způsob pro formátování řetězců. Starý způsob lze stále použít, ale je deprecated a v budoucích verzích (nejspíš ale za dlouho) bude odstraněn. Proto byste měli používat spíše ten nový způsob.
Po staru
S řetězci lze použít přetížený operátor % (který se normálně používá na zjištění zbytku po dělení).
K formátování se používají sekvence začínající taky procenterm, téměř stejně jako v jazyce C. Do těchto sekvencí se dosazují hodnoty pomocí n-tice.
>>> print(x)
cislo 4.0000 a retezec 4
>>> x = 'cislo %i a retezec "%s"' % (4, x)
>>> print(x)
cislo 4 a retezec "cislo 4.0000 a retezec 4"
Za výraz %i nebo %d se dosazuje celé číslo, za %s řetězec, za %f racionální číslo (číslo s desetinnou čárkou) atd.
Na dalším příkladě je vidět, jak můžete pomoci % sekvence ovlivnit délku výstupu.
'retezec a retezec'
>>> 'retezec %-20s retezec' % 'a'
'retezec a retezec'
>>> 'retezec %2d retezec' % 4
'retezec 4 retezec'
>>> 'retezec %05d retezec' % 4 #délka 5 znaků, doplněno nulami
'retezec 00004 retezec'
>>> 'retezec %-10.2f retezec' % 4 # délka 10 znaků, 2 desetinná místa
'retezec 4.00 retezec'
Poslední vymožeností operátoru % je v použití slovníku. Za % lze uvést do kulatých závorek jméno klíče a tím zajistit přiřazení správné hodnoty ze slovníku.
>>> 'tady je text "%(text)s" a tady cislo %(cislo2)i' % slovnik
'tady je text "abcdefg" a tady cislo 456'
Po novu
Od verze 3.0 přibila řetězcům metoda format()
.
Ta nahradí v řetězci {}
svými argumenty.
Do složených závorek je možné napsat index argumentu, kterým se mají závorky
nahradit.
Hello world!
>>> print("{1} {0} {1}!".format("baby","go"));
go baby go!
Pokud předáte argumenty metodě format()
pojmenované,
může te se na jména odkazovat místo indexů. Oba způsoby se dají míchat
go baby go!
Za index nebo jméno argumentu můžete napsat dvojtečku a formátování
výstupu, obdobně jako jsem popisoval jak se to dělá po staru.
Všiměte si, že místo mínus se k zarovnání do leva používá závorka <.
0.8 => 1
A jako poslední ukázku si dovolím použít příklad z oficiálního
tutoriálu,
který ukazuje, jak můžete využít slovníky pro předání argumentů metodě
format()
.
>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '
... 'Dcab: {0[Dcab]:d}'.format(table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}}'.format(**table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
Podrobný popis formátování najdete v dokumentaci. Dočtete se tam například, že typ s, nebo neuvedení typu formátu se bere jako řetězec, c jako znak (takže celé číslo se zkonvertuje na odpovídající unicode znak), d je celé číslo, f je číslo s desetinnou čárkou. A mnohé další drobnosti.
Metody
Některé metody řetězce:
strip(), lstrip(), rstrip()
odstraní bílé znaky ze začátku a (nebo) konce řetězceendswith()
vrátí True, pokud řetězec končí řetezcem předaným jako argumentfind()
hledá podřetězec v řetězci, vrací jeho index, nebo -1, když jej nenajde
' adfasdf'
>>> " adfasdf ".lstrip()
'adfasdf '
>>> " adfasdf ".strip()
'adfasdf'
>>> "soubor.txt".endswith(".txt")
True
>>> "soubor.txt".find(".txt")
6
Všechny metody si můžete, jako vždy, vytisknout příkazem dir("")
.