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ěla.
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?"')
Zpětným lomítkem se dají přidávat i
exotické znaky, které nemáš na klávesnici.
Ty se dají zapsat jako \N
a jméno znaku
v složených („kudrnatých“) závorkách.
Třeba následující znaky.
(Do konzole na Windows bohužel nemusí jít všechny
vypsat, ale aspoň první by jít měl):
print('--\N{LATIN SMALL LETTER L WITH STROKE}--')
print('--\N{SECTION SIGN}--')
print('--\N{PER MILLE SIGN}--')
print('--\N{BLACK STAR}--')
print('--\N{SNOWMAN}--')
print('--\N{KATAKANA LETTER TU}--')
Tahle vychytávka má jeden, někdy nepříjemný,
důsledek: pokud chceš použít zpětné lomítko
(třeba ve jménech souborů na Windows),
musíš ho ve zdrojovém kódu zdvojit.
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? Dostala jsi opravdu páté písmeno?
Jak sis možná už všimla, 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řebovala 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ěla porovnávat bez ohledu na velikost písmen,
musela 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()
a lower()
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ý.
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 metoda format
,
která v rámci řetězce nahradí dvojice „kudrnatých“ závorek
za to, co dostane v argumentech:
vypis = '{}×{} je {}'.format(3, 4, 3 * 4)
print(vypis)
Řetězec '{}×{} je {}'
tady funguje jako šablona (angl. template).
Představ si to jako jako formulář, do kterého Python na vyznačená místa
vpisuje hodnoty.
Pokud chceš nahradit hodnoty v jiném pořadí, nebo když chceš aby šablona byla čitelnější, můžeš do „kudrnatých“ závorek napsat jména:
vypis = 'Ahoj {jmeno}! Výsledek je {cislo}.'.format(cislo=7, jmeno='Elvíro')
print(vypis)
Formátování se používá skoro všude, kde je potřeba „hezky“ vypsat nějakou hodnotu.
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 funkci zamen(retezec, pozice, znak)
.
Tato funkce vrátí řetězec, který má na dané pozici
daný znak; jinak je stejný jako původní retezec
. Např:
zamen('palec', 0, 'v') == 'valec'
zamen('valec', 2, 'j') == 'vajec'
Pozor na to, že řetězce v Pythonu nelze měnit. Musíš vytvořit nový řetězec poskládaný z částí toho starého.