Lekce 14 - Textové řetězce v Pythonu do třetice - Split a Join
V předešlém cvičení, Řešené úlohy k 13. lekci Pythonu, jsme si procvičili nabyté zkušenosti z předchozích lekcí.
V dnešním Python tutoriálu navážeme na předchozí lekce, v nichž jsme
se naučili zacházet s řetězci jako se sekvencemi znaků. Ukážeme si metody
split()
a join()
. Díky nim si pak budeme moci
vytvořit program pro kódování a dekódování Morseovy abecedy.
Metody split()
a
join()
Z předchozích tutoriálů víme, že parsování řetězce po znaku může být někdy docela složité. S řetězci se samozřejmě budeme setkávat stále, a to jak na vstupu od uživatele (např. z konzole nebo ze sekvencí ve formulářových aplikacích), tak i při práci se soubory. Velmi často máme zadán jeden delší řetězec (řádek souboru nebo řádek konzole), ve kterém je více hodnot. Ty jsou oddělené tzv. separátory, např. čárkou. V tomto případě hovoříme o formátu CSV (Comma-separated values, tedy hodnoty oddělené čárkou). Abychom si byli jistí, že víme, o čem hovoříme, ukažme si nějaké ukázkové řetězce:
Jan, Novák, Dlouhá 10, Praha 3,130 00 .. ... .-.. .- -. -.. ... --- ..-. - (1,2,3;4,5,6;7,8,9)
Význam jednotlivých řetězců:
- První řetězec je očividně nějaký uživatel. Takto bychom mohli realizovat např. uložení uživatelů do CSV souboru, každý na jeden řádek.
- Druhý řetězec jsou znaky Morseovy abecedy, separátorem (oddělovačem) je zde mezera.
- Třetí řetězec je matice o třech sloupcích a třech řádcích. Oddělovačem sloupců je čárka, řádků středník.
Na datovém typu str
můžeme volat metodu split()
,
která bere jako parametr separátor. Metoda následně původní řetězec
rozdělí podle separátorů na sekvenci podřetězců, které vrátí.
Defaultním separátorem je mezera. To nám velmi ulehčí práci při
rozdělování hodnot v řetězci. Z příkladu je to zřejmé:
zprava = "Už toho v Pythonu umím docela dost."
x = zprava.split()
print(x)
Metoda join()
se volá přímo na typu str
a
umožňuje nám naopak sekvenci podřetězců spojit oddělovačem do jediného
řetězce. Parametry jsou oddělovač a sekvence. Výstupem metody je výsledný
řetězec. Uveďme si příklad:
moje_parta = ("Jirka", "Petr", "Andrea")
x = ", ".join(moje_parta)
print(x)
Jelikož zatím neumíme tvořit objekty (uživatele) ani pracovat s vícerozměrnými seznamy (matice), zkusíme si naprogramovat dekodér zpráv z Morseovy abecedy.
Dekodér Morseovy abecedy
Pojďme si opět připravit strukturu programu. Budeme potřebovat dva řetězce se zprávou, jeden se zprávou v Morseově abecedě, druhý zatím prázdný, do kterého budeme ukládat výsledek našeho snažení. Dále budeme jako v případě samohlásek potřebovat nějaký vzor písmen. K písmenům budeme muset přiřadit vzor jejich znaku v morseovce. Písmena můžeme opět uložit do pouhého řetězce, protože mají jen jeden znak. Symboly Morseovy abecedy mají již znaků více, proto je musíme dát do seznamu. Struktura našeho programu bude nyní vypadat následovně:
# řetězec, který chceme dekódovat sifrovana_zprava = ".-.. . --- -. .- .-. -.. ---" print(f"Původní zpráva: {sifrovana_zprava}") # řetězec s dekódovanou zprávou zprava = "" # vzorová sekvence abecedni_znaky = "abcdefghijklmnopqrstuvwxyz" morseovy_znaky = [".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."]
Můžeme samozřejmě přidat i další znaky jako čísla či interpunkční znaménka, my je zde však vynecháme.
Nyní si řetězec sifrovana_zprava
rozbijeme metodou
split()
na seznam podřetězců, obsahujících jednotlivé znaky
morseovky. Rozdělovat budeme podle znaku mezery. Seznam si následně
proiterujeme cyklem for
:
# rozbití řetězce na znaky morseovky znaky = sifrovana_zprava.split(" ") # iterace znaky morseovky for morseuv_znak in znaky: pass
Ideálně bychom se měli nějak vypořádat s případy, kdy uživatel zadá
např. více mezer mezi znaky (to uživatelé dělají rádi). Metoda
split()
poté vytvoří o jeden řetězec v poli více, který bude
prázdný. Ten bychom měli poté v cyklu detekovat a ignorovat. My se tím
však v tomto tutoriálu zabývat nebudeme.
V cyklu se pokusíme najít aktuálně čtený znak morseovky v seznamu
morseovy_znaky
. Bude nás zajímat jeho index, protože když se
podíváme na tentýž index v seznamu abecedni_znaky
, bude tam
odpovídající písmeno. To je způsobeno samozřejmě tím, že jak seznam,
tak řetězec obsahují stejné znaky seřazené dle abecedy. Umístěme tedy do
těla cyklu následující kód:
for morseuv_znak in znaky: abecedni_znak = "?" try: index = morseovy_znaky.index(morseuv_znak) abecedni_znak = abecedni_znaky[index] zprava += abecedni_znak except ValueError: # znak nenalezen zprava += abecedni_znak
Kód nejprve do abecedního znaku uloží znak ?
, protože se
může stát, že znak v naší sadě nemáme. Následně se pokusíme zjistit
jeho index. Pokud se to podaří, dosadíme do proměnné
abecedniZnak
znak z abecedních znaků pod tímto indexem. Nakonec
znak připojíme ke zprávě. Pokud však kód znak v sadě
morseovyZnaky
nenajde, vloží místo něj ?
.
Operátor +=
nahrazuje zápis
zprava = zprava + abecedniZnak
.
Na závěr samozřejmě zprávu vypíšeme:
# řetězec, který chceme dekódovat
sifrovana_zprava = ".-.. . --- -. .- .-. -.. ---"
print(f"Původní zpráva: {sifrovana_zprava}")
# řetězec s dekódovanou zprávou
zprava = ""
# vzorové seznamy
abecedni_znaky = "abcdefghijklmnopqrstuvwxyz"
morseovy_znaky = [".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
"...-", ".--", "-..-", "-.--", "--.."]
# rozbití řetězce na znaky morseovky
znaky = sifrovana_zprava.split(" ")
# iterace znaky morseovky
for morseuv_znak in znaky:
abecedni_znak = "?"
try:
index = morseovy_znaky.index(morseuv_znak)
abecedni_znak = abecedni_znaky[index]
zprava += abecedni_znak
except ValueError: # znak nenalezen
zprava += abecedni_znak
print(f"Dekódovaná zpráva je: {zprava}")
Výstup programu:
Úspěšně dekódovaná zpráva:
Původní zpráva: .-.. . --- -. .- .-. -.. ---
Dekódovaná zpráva je: leonardo
Hotovo! Za úkol si nyní zkusme naprogramovat program, který naopak
zakóduje řetězec do morseovky. Jeho kód bude velmi podobný. S metodami
split()
a join()
se setkáme během Python kurzu
ještě několikrát.
Tímto jsme v podstatě zakončili kurz se základní strukturou jazyka Python. V příštích lekcích si uvedeme vícerozměrná pole a matematické operace. Ze základních konstrukcí jazyka nás tu ale již nic nepřekvapí V podstatě bychom se již mohli klidně věnovat i objektům. Doporučujeme však zbylé tutoriály také projít, jedná se přece jen stále o základní znalosti, které bychom měli mít.
V následujícím kvízu, Kvíz - Textové řetězce v Pythonu, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 248x (1.29 kB)
Aplikace je včetně zdrojových kódů v jazyce Python