Teď se podíváme na zoubek řetězcům (angl. strings). Už víš, jak je zapisovat:
'tohle je řetězec'
"tohle taky"
Někdy potřebuješ řetězce, které obsahují více řádků. Pythonní řetězce ale můžeš normálně napsat jen na jeden řádek. Jinak by koncová uvozovka mohla být kdekoli a špatně by se hledala, kdybys na ni zapomněl/a.
Můžeš ale do řetězce znak pro nový řádek vložit pomocí speciálního
zápisu \n
:
print('Haló haló!\nCo se stalo?')
Obecně zpětné lomítko umožňuje zapsat znaky, které by se špatně zadávaly.
Třeba uvozovka se dá zapsat jako \"
a „apostrof“ jako \'
.
To se dá použít, když potřebuješ mít v jednom
řetězci uvozovku i apostrof:
print("Vtom vnuk křik': \"Hleď!\"")
print('"Jen ho nech," řek\' děd. "Kdo zná líp kraj?"')
Sekvence \\
znamená „jedno zpětné lomítko“.
print('C:\\PyLadies\\Nový adresář')
Ale zpátky k řetězcům na více řádků. Kromě \n
je i druhý způsob, jak takový
řetězec zadat: ohraničit ho třemi uvozovkami (jednoduchými nebo dvojitými)
na každé straně:
basen = '''Haló haló!
Co se stalo?
Prase kozu potrkalo!'''
Takové dlouhé texty nachází uplatnění třeba v dokumentačních řetězcích u funkcí.
def vynasob(a, b):
"""Vynásobí argumenty a vrátí výsledek.
Oba argumenty by měly být čísla.
"""
return a * b
Jen pozor na to, že pokud je tenhle řetězec v odsazeném kódu, každý jeho řádek bude začínat několika mezerami. (V dokumentačních řetězcích to nevadí, tam se s odsazením počítá.)
Tolik k zápisu řetězců. Teď se podíváme, jak se zadanými řetězci pracovat.
Už umíš spojovat dohromady kratší řetězce:
spojeny_retezec = 'a' + 'b'
dlouhy_retezec = 'ó' * 100
Teď se podíváme na opačný proces: jak z dlouhého řetězce dostat kratší součásti. Začneme jednotlivými znaky. Dělá se to operací vybrání prvku (angl. subscripting), která se píše podobně jako volání funkce, jen s hranatými závorkami:
pate_pismeno = 'čokoláda'[5]
print(pate_pismeno)
Funguje to? Dostal/a jsi opravdu páté písmeno?
Jak sis možná už všiml/a, programátoři počítají od nuly. „První“ prvek má vždy číslo nula, druhý číslo jedna a tak dál.
Stejně je to i s písmeny v řetězcích: první písmeno má číslo nula, druhé jedna, ... a osmé písmeno má číslo sedm.
Proč je tomu tak? K úplnému pochopení důvodů by ses potřeboval/a naučit něco o ukazatelích a polích, což nebude hned, takže pro teď nám bude stačit vědět, že programátoři jsou prostě divní.
A nebo že mají rádi divná čísla jako nulu.
[0] [1] [2] [3] [4] [5] [6] [7]
╭───┬───┬───┬───┬───┬───┬───┬───╮
│ Č │ o │ k │ o │ l │ á │ d │ a │
╰───┴───┴───┴───┴───┴───┴───┴───╯
A když už jsme u divných čísel, co se asi stane, když budu chtít vybírat písmena pomocí záporných čísel?
Řetězce umí i jiné triky. Třeba můžeš zjistit, jak je řetězec dlouhý nebo jestli v sobě obsahuje daný menší řetězec.
Zápis | Popis | Příklad |
---|---|---|
len(r) |
Délka řetězce | len('čokoláda') |
x in r |
True pokud je řetězec x obsažen v r |
'oko' in 'čokoláda' |
x not in r |
Opak x in r |
'dub' not in 'čokoláda |
Řetězce vždy berou v potaz velikost písmen,
takže např. 'ČOKO' in 'čokoláda'
je False
.
Kdybys chtěl/a porovnávat bez ohledu na velikost písmen,
musel/a bys oba řetězce převést třeba na malá písmena
a pak je porovnat.
A jak se převádí na malá písmena? K tomu budeme potřebovat další novou vlastnost Pythonu: metody.
Metoda (angl. method) je jako funkce – něco, co se dá zavolat. Na rozdíl od funkce je svázaná s nějakým objektem (hodnotou). Volá se tak, že se za objekt napíše tečka, za ní jméno metody a za to celé se, jako u funkcí, připojí závorky s případnými argumenty.
Řetězcové metody upper()
, lower()
nebo title()
převádí text na velká, respektive malá písmena.
retezec = 'Ahoj'
print(retezec.upper())
print(retezec.lower())
print(retezec)
Všimni si, že původní řetězec se nemění; metoda vrátí nový řetězec, ten starý zůstává.
To je obecná vlastnost řetězců v Pythonu: jednou existující řetězec se už nedá změnit, dá se jen vytvořit nějaký odvozený.
Máme i jiné metody co naopak něco zjištují např. islower()
, isupport()
nebo istitle()
.
Vrací True
nebo `False.
retezec = 'Ahoj'
print(retezec.islower())
print(retezec.istitle())
Metod je u řetězců mnohem více. Pro výpis všech můžeš použít funkci dir('Ahoj')
.
Pro procvičení metod a vybírání znaků si zkus napsat program, který se zeptá na jméno, pak na příjmení a pak vypíše iniciály – první písmena zadaných jmen.
Iniciály jsou vždycky velkými písmeny (i kdyby byl uživatel líný mačkat Shift).
Řetězcových metod je celá řada. Nejužitečnější z nich najdeš v taháku, který si můžeš stáhnout či vytisknout.
A úplně všechny řetězcové metody jsou popsány v dokumentaci Pythonu (anglicky; plné věcí, které ještě neznáš).
Všimni si, že len
není metoda, ale funkce; píše se len(r)
, ne r.len()
.
Proč tomu tak je, to za nějakou dobu poznáš.
Obzvláště užitečné je formátování pomocí tzv. F-stringů,
kdy před uvozovkama napíšeme znak f
a pomocí složených závorek můžeme, referencovat proměnnou
takto f'Moje jméno je: {my_name}'
.
a = 3
b = 5
vypis = f'Obdelník o stranách {a}×{b}cm má obvod {2 * a + 2 * b}cm.'
print(vypis)
Teď se vrátíme k vybírání kousků řetězců. Zkus, co dělá tenhle program:
retezec = 'čokoláda'
kousek = retezec[5:]
print(kousek)
Dá se použít i retezec[:5]
,
který vybere všechno až po znak číslo 5.
Ale ne znak 5 samotný, takže retezec[:5] + retezec[5:] == retezec
.
Co asi udělá retezec[2:5]
?
A co retezec[-4:]
?
retezec = 'čokoláda'
print(retezec[:4])
print(retezec[2:5])
print(retezec[-4:])
Určování vhodných čísel, indexů, občas vyžaduje trochu zamyšlení.
U podobného „sekání“ (angl. string slicing) je lepší si číslovat „hranice“ mezi znaky. Člověk tomu pak lépe rozumí:
╭───┬───┬───┬───┬───┬───┬───┬───╮
│ Č │ o │ k │ o │ l │ á │ d │ a │
├───┼───┼───┼───┼───┼───┼───┼───┤
│ │ │ │ │ │ │ │ │
0 1 2 3 4 5 6 7 8
-8 -7 -6 -5 -4 -3 -2 -1
╰───────────────╯
'čokoláda'[:4] == 'čoko'
╰───────────────╯
'čokoláda'[2:6] == 'kolá'
╰───────────╯
'čokoláda'[-3:] == 'áda'
Zkus napsat program, který vymění znak na dané pozici řetězce za jiný. Od uživatele vyžádá řetězec, pozici, na které se má provést výměna a znak, který se má na pozici zadat. Pozor na to, že řetězce v Pythonu nelze měnit. Musíš vytvořit nový řetězec poskládaný z částí toho starého.