V minulém díle jste viděli…¶
Základní kontejnery:
str
(string neboli textový řetězec) – posloupnost znakůlist
(seznam) – modifikovatelná (mutable) posloupnost libovolných objektůtuple
(n-tice) – nemodifikovatelná (immutable) posloupnost libovolných objektůset
(množina) – datová struktura obsahující objekty, pro které není určené jejich vzájemné pořadídict
(slovník) – datová struktura, která představuje zobrazení z množiny klíčů (keys) na libovolné hodnoty (values)
Základní operace s kontejnery:
- testování:
var in container
– výraz s hodnotouTrue
/False
- iterování:
for var in container
Také vždy můžeme použít funkci len(container)
, která vrací délku neboli počet prvků kontejneru.
Na rozdíl od posloupností, prvky množin nemají určené pořadí, každá hodnota se může vyskytovat nejvýše jednou. Přitom set
reprezentuje modifikovatelnou (mutable) množinu, frozenset
– nemodifikovatelnou (immutable) množinu. S jejichž prvky je možné provádět všechny obvyklé matematické operace.
Slovník (dict
) je modifikovatelná (mutable) datová struktura, zobrazení z množiny klíčů (keys) na libovolné hodnoty (values). Klíče slovníku se opakovat nemohou (tedy jsou hashovatelné), hodnoty ale nemusí být unikátní.
Pro zápis množin i slovníků se v kódu používají složené závorky, ale se syntaktickým rozdílem kvůli mapování klíčů na hodnoty v slovníků. Tomu v slovníků slouží dvojtečka.
my_set = {1, 2, 3}
my_dict = {1: "a", 2: "b", 3: "c"}
V případě, když necháme složené závorky prázdné, nedostaneme prázdnou množinu ale slovník.
var = {} # dict
print(isinstance(var, dict))
var = set() # set
print(isinstance(var, dict))
True False
Pokud chceme zpracovávat jen množinu klíčů, můžeme explicitně použít přístupovou metodu keys()
, pro hodnoty – metodu values()
, pro dvojice (key, value)
je možné použít metodu items()
.
Kontejnery mohou být předávány jako argumenty funkcí stejně jako jiné objekty v Pythonu. Použití modifikovatelných kontejnerů jako parametrů může ale způsobit problémy. V tomto případě modifikace kontejneru uvnitř funkce může ovlivnit i objekt mimo funkci. V upravení problematického chování může pomoct objekt None
v definici funkce, který slouží pro odlišení, jestli byl parametr specifikován nebo ne.
Přiřazovací operátor (např. a = b
) pouze nastaví odkaz na stejný objekt. Umíme ale vytvořit skutečnou kopii kontejneru – mělkou nebo hlubokou.
Textové řetězce¶
Jsme již definovali kontejner, který se jmenuje textový řetězec. Je to spíš oficiální název, mezi programátory je velmi často označují jako stringy. Nejčastěji textové řetězce slouží k uchovávání různých textů. V podstatě ale jsou to sekvence docela libovolných znaků. Na rozdíl od řady jiných programovacích jazyků, stringy v Pythonu jsou neměnné nebo nemodifikovatelné (immutable) posloupnosti a dokonce hashovatelné. To znamená, že vždy po nějaké "modifikovatelné" operaci dostaneme nový string, nikdy neměníme počáteční hodnotu. Stringy jsou instancemi třídy str
. Kvůli tomu, že je to třída (anglicky class), budeme moci používat metody té třidy, které se volají o něco jinak než obyčejné funkce. To ale podrobně uvidíme později.
Poznámka:
Může to na první pohled vypadat překvapivě, ale Python nezavádí samostatný datový typ pro znaky (např. jako char
v jazyce C/C++). Znaky se v Pythonu zadávají jako stringy obsahující pouze jeden znak. Druhou možností je převést znak na jeho kód, a pracovat dále s tímto číslem. Jak to udělat, uvidíme dále.
Vytváření řetězců a escape sekvence¶
Nejjednodušší variantou je vytvoření řetězce pomocí jednoduchých (apostrofy) nebo dvojitých uvozovek. Jejich význam se nijak neliší, jen musíme dbát na to, abychom hraniční znak použitý na počátku použili i na konci toho stringu.
prvni_prazdny_textovy_retezec = ""
druhy_prazdny_textovy_retezec = ''
prvni_neprazdny_textovy_retezec = "Python"
druhy_neprazdny_textovy_retezec = 'C++'
Podobně jako 1.0
a 1.000
jsou dva zápisy téhož čísla, tak 'slovo'
a "slovo"
pro Python označuje stejnou hodnotu, skládající se ze stejných pěti písmen. Použité uvozovky nejsou součástí hodnoty – Python si "nepamatuje", jakým způsobem byl řetězec uvozen. Volba hraničních znaků může být ovlivněna tím, zda potřebujeme některý z nich použít uprostřed textu.
s1 = "Potřebuji 'apostrofy'"
s2 = 'Potřebuji "uvozovky"'
print(s1)
print(s2)
Potřebuji 'apostrofy' Potřebuji "uvozovky"
V konzolovém režimu Python dává při zobrazení stringů přednost jednoduchým uvozovkám. Dvojité uvozovky použije k ohraničení textu pouze tehdy, je-li ve vypisovaném textu apostrof. Při zobrazení stringů pomocí funkce print()
vypíše samozřejmě pouze hodnotu bez žádných uvozovek.
V případě, když bude potřeba vytvořit řetězec skládající z několika řádku, je možné použit tzv. escapování. Escapování znaků znamená, že před nějakým znakem budeme psát zpětné lomítko (\
). Zpětné lomítko určí, že se začíná speciální posloupnost, kterou však často nenazvou jinak než escape sekvence (slangový anglický termín escape sequence). Tuto sekvenci má Python interpretovat jako jediný speciální znak. Někdy se escape sekvence používají pro vyvolání nějaké akce terminálu. Pak žádný "viditelný" znak zobrazen nebude. \n
označuje přechod na nový řádek.
print("Několika\nřádkový\ntext")
Několika řádkový text
Pomocí escapování také bylo možné vypsat jednoduché a dvojité uvozovky i když je potřeba použit ten samý druh uvozovek pro obklopení. Tomu slouží \'
, resp. \"
.
print("Teď potřebuji \'apostrofy\' i \"uvozovky\"")
print('Teď potřebuji \'apostrofy\' i \"uvozovky\"')
Teď potřebuji 'apostrofy' i "uvozovky" Teď potřebuji 'apostrofy' i "uvozovky"
Tato vychytávka použití zpětného lomítka k určení escape sekvencí má jeden, někdy nepříjemný, důsledek. Pokud máme zpětné lomítko jako součást řetězce (třeba v adresách souborů na OS Windows), nemůžeme použít přímo \
. Musíme použít speciální sekvenci \\
– tedy lomítko zdvojit.
print("C:\\ZPRO\\Nový adresář")
C:\ZPRO\Nový adresář
print("abcde \101")
print("abcde \x41")
print("abcde \u0041")
print("abcde \U00000041")
abcde A abcde A abcde A abcde A
Tyto a některé další příklady escape sekvencí v Pythonu jsou v tabulce níže.
Sekvence | Krátký popis |
---|---|
\' |
Jednoduché uvozovky nebo apostrof (kód \x27 ). |
\" |
Dvojité uvozovky (kód \x22 ). |
\\ |
Zpětné lomítko (kód \x5c ). |
\n |
Nový řádek (New Line – NL – kód \x0a ). |
\t |
Vodorovný tabulátor (TAB nebo HT – kód \x09 ). |
\v |
Svislý tabulátor (Vertical Tab – VT – kód \x0b ). |
\b |
Backspace (BS – smazání předchozího znaku – kód \x08 ). |
\r |
Návrat vozíku (Carriage Return – CR – kód \x0d ). |
\ooo |
Znak s 8bitovým kódem zadaným v osmičkové soustavě, o představuje osmičkovou číslici – např. '\101' == 'A' . |
\xhh |
Znak s 8bitovým kódem zadaným v šestnáctkové soustavě, h představuje šestnáctkovou číslici – např. '\x42' == 'B' . |
\uhhhh |
Znak s 16bitovým kódem zadaným v šestnáctkové soustavě, h představuje šestnáctkovou číslici – např. '\u263A' == '☺' . |
\Uhhhhhhhh |
Znak s 32bitovým kódem zadaným v šestnáctkové soustavě, h představuje šestnáctkovou číslici – např. '\U0000266b' == '♫' . |
\N{název} |
Znak, který má v sadě Unicode zadaný název – např. '\N{DEGREE CELSIUS}' == '\u2103' == '℃' nebo '\N{WHITE SMILING FACE}' == '\u263a' == '☺' . |
Jak je vidět z tabulky, se zpětným lomítkem se dá zadat jakýkoli znak – včetně emoji – podle názvu nebo kódu standardu Unicode. Stačí přesné jméno nebo číslo znát (nebo dohledat to na internetu). Jen pro zajímavost zkuste doplnit následující příklad použitím tabulátorů, \b
, \r
a výpisem nějakých "nestandardních" znaků sady Unicode.
print("\N{GREEK CAPITAL LETTER DELTA}")
print("\N{SECTION SIGN}")
print("\N{GRINNING CAT FACE WITH SMILING EYES}")
print("\u30C4")
Δ § 😸 ツ
Poznámka:
Ke konverzi standardních "kódů" emoji na jejich "obrázky", které se běžně používají na sociálních sítích a messengerech (třeba :thumbs_up:
), pro Python existuje dost jednoduchý modul emoji
(https://pypi.org/project/emoji/). Instalací a použitím "vnějších" modulů v Pythonu se ale podrobně zabývat během ZPRO neplánujeme.
Použití \n
ale někdy může být příliš komplikovaným způsobem k odřádkování velkých textů. V tomto případě zadávaný text je možné ohraničit trojicemi jednoduchých nebo dvojitých uvozovek. Tak Python bude konec řádku považovat za součást zadávaného textu, dokud nenajde uzavírající trojici. Něco podobného jsme již viděli ve víceřádkových komentářích a docstringech funkcí.
s1 = "Jsem víceřádkový string\nobklopený dvojitými uvozovkami\na obsahující escapování pro nové řádky."
s2 = '''Jsem také
víceřádkový string,
ale vytvořený pomocí
trojic jednoduchých uvozovek.'''
print(s1)
print(s2)
Jsem víceřádkový string obklopený dvojitými uvozovkami a obsahující escapování pro nové řádky. Jsem také víceřádkový string, ale vytvořený pomocí trojic jednoduchých uvozovek.
Převod na string a opačně¶
Pravda je, že s textovými řetězci jsme pracovali od začátku našich cvičení. To bylo již tehdy, jakmile jsme se seznámili s funkcí input()
pro čtení vstupu od uživatele. Připomeňme si, že tato funkce vždy nám vrací textový řetězec (kromě případu, když bude splněná podmínka EOF
– end-of-file – pak se vyvolává výjimka EOFError
). Potom jsme pravidelně používali přetypovaní na nějaké číslo, aby to bylo možno používat ve výpočtech. K tomu nám nejprve sloužili funkce int()
a float()
.
Ve funkci int(x, base=10)
prvním argumentem se předpokládá objekt, který lze převést na celé číslo. Konkrétní textový řetězec zřejmě je objekt – instance třidy str
(podrobněji se budeme věnovat pojmům třida – instance – typ na konci semestru, když budeme probírat základy objektově orientovaného programování). V případě, pokud prvním argumentem x
je string, funkce int()
požaduje, aby on vyhovoval pravidlům pro zápis celého čísla v desítkové soustavě, na něž jej převede. Přitom jsou povoleny pouze úvodní a závěrečné bílé znaky (mezera, tabulátor, nový řádek atp.). Není-li zadán argument, vrátí nulu.
Je-li zadán druhý argument base
(2 <= base <= 36
) pak v prvním argumentu je očekáván string reprezentující celé číslo zadané v číselné soustavě definované druhým argumentem. Pamatujeme si, že v tom zápise jsou povolena zpřehledňovací podtržítka, mezery být nesmí. Číselné soustavy se základem větším než 10 používají v roli dalších číslic písmena A
–Z
, resp. a
–z
. Velikost použitých písmen přitom roli nehraje.
print(int())
print(int("1"))
print(int("1010", 2))
print(int("1010", 16))
print(int("No_nazdar", 36))
0 1 10 4112 1856027718675
Funkce float(x=0.0)
vrátí "reálné" číslo vytvořené ze zadaného čísla či stringu. Je-li argumentem string, požaduje, aby vyhovoval pravidlům pro zápis reálného čísla, na něž jej převede. Jsou povoleny pouze úvodní a závěrečné bílé znaky. Není-li zadán argument, vrátí nulu.
print(float())
print(float("3_513"))
print(float(" -3.5\n"))
print(float("-Infinity")) # -Nekonečno, také jsou možné zkratky inf, -Inf apod.
#print(float("NaN")) # Not a Number - není číslo
#print(float("Číslo 1.1")) # ValueError
0.0 3513.0 -3.5 -inf
Dalšími možnostmi jsou převody na complex
a bool
.
Funkce complex(string)
vrací hodnotu typu complex
, pokud argument string je korektní zápis komplexního čísla v algebraickém tvaru dle Pythonovské notaci. Mezery mezi reálnou a imaginární částmi nejsou povoleny.
print(complex("1+2j"))
#print(complex("1 + 2j")) # ValueError
(1+2j)
Pokud chceme převést řetězec na booleovskou hodnotu pomocí funkce bool(x=False)
, tak se prázdný řetězec vyhodnotí na False
a jakýkoli neprázdný na True
.
print(bool(""))
print(bool("0"))
print(bool("False")) # pozor
False True True
Nakonec řekněme pár slov o zpětném převádění na typ str
. Tomu slouží funkce str(object='')
, která převede argument object
na string. Není-li zadán argument, vrátí prázdný textový řetězec. Existuje také funkce repr(object)
, která se snaží vrátit jednoznačný textový podpis objektu (systémový podpis – v řadě případu je jím text, po jehož zadání překladač vytvoří ekvivalentní objekt). Tuto funkci právě volá systém, když nám zobrazuje zadanou hodnotu v konzolovém režimu. Funkce str()
ale vrací "klasický" string, který by měl být pro člověka co nejsrozumitelnější – uživatelský podpis. Návratové hodnoty funkcí str()
a repr()
jsou velmi často shodné, ale občas se liší. Typickým příkladem jsou texty, pro něž funkce str()
vrací zadaný text, kdežto funkce repr()
vrací text uzavřený v apostrofech, resp. v uvozovkách (obsahuje-li text apostrofy), tj. text, který můžeme zadat do programu.
print(str('Python'), str("Python"), str("""Python"""))
print(repr('Python'), repr("Python"), repr("""Python"""))
x = str("""Python""")
s = list(x)
print(s)
y = repr("""Python""")
s = list(y)
print(s)
Python Python Python 'Python' 'Python' 'Python' ['P', 'y', 't', 'h', 'o', 'n'] ["'", 'P', 'y', 't', 'h', 'o', 'n', "'"]
Základní funkce a operace s textovými řetězci¶
Především string je základní kontejner v Pythonu. Proto pro hodnoty typu str
je možné použití všech základních operací jako testování (in
a not in
) a iterování. Přirozeně můžeme používat indexování znaků v stringu (Python umožňuje i záporné indexy) a slicing nebo vykrajování. Výsledkem výrazu my_string[i:j]
bude textový řetězec, který obsahuje všechny znaky původního řetězce my_string
od pozice i
do pozice j
(a ta pozice j
ne včetně). Defaultní hodnotou i
, pokud ji nezadáme, bude 0
, není-li zadané j
, dosadí se na to místo délka řetězce. Délku stringu se můžeme dozvědět s funkcí len()
. Toto jsme v detailech měly v jednom z předchozích cvičení.
Poznámka:
Ještě jedním zajímavým příkladem slicingu je použití třech parametrů. my_string[i:j:k]
vybere každý k
-tý znak v rozmezí pozic od i
do j-1
.
my_string = "Everybody loves ZPRO with Python!"
if 'e' in my_string:
print("ano")
for i in range(len(my_string)):
print(my_string[i], end = " ")
print("")
for x in my_string:
print(x, end = " ")
print("")
print(my_string[-1])
#my_string[-1] = "2" # chyba!
print(my_string[ : :-1])
print(my_string[2:25:2])
l = len(my_string)
print(l)
ano E v e r y b o d y l o v e s Z P R O w i t h P y t h o n ! E v e r y b o d y l o v e s Z P R O w i t h P y t h o n ! ! !nohtyP htiw ORPZ sevol ydobyrevE eyoylvsZR ih 33
Teď se zaměříme na funkce a operace bezprostředně se stringy.
Sčítání a násobení pro stringy¶
Pro textové řetězce můžeme používat "aritmetické" operace +
a *
. Sčítání stringů je implementováno jako jejich skládání nebo zřetězení (anglicky concatenation), a to nezávisí na tom, jakým způsobem jsou jednotlivé sčítance zadány, tj. zda je ohraničují jednoduché, dvojité uvozovky nebo jejich trojice. Jsou-li oba texty zadány jako tzv. stringové literály – textové konstanty nazvané svojí hodnotou (a nejsou třeba výsledky volání nějakých funkcí), tak Python povoluje nevkládat mezi ně operátor +
. Je to něco obdobného, jako když v matematice nemusíme psát znak násobení a píšeme $3ab$ místo $3 \cdot a \cdot b$, resp. $3×a×b$. Na rozdíl od některých dalších programovacích jazyků, Python nepovoluje přičítat k textu něco jiného než text. Před přičtením hodnoty jiného druhu ve smyslu skládání musíme tuto hodnotu nejprve převést na text.
print("Jedna" + """Dva""" + 'Tři' '''Čtyři''')
print("Jedna: " + str(1))
#print("Jedna: " + 1) # TypeError
# print("Jedna" str(1)) # SyntaxError
JednaDvaTřiČtyři Jedna: 1
Operace *
není násobení dvou stringů ale může se používat pro násobení textů celým číslem. Výsledkem bude text, v němž se textový činitel opakuje tolikrát, kolik je hodnota číselného činitele (na pořadí činitelů nezáleží).
print("Pam" * 3)
print(2 * "Ha")
print(int(2.0) * "Ha")
# print(2.0 * "Ha") # TypeError
PamPamPam HaHa HaHa
Funkce chr()
a ord()
¶
Funkce chr()
a ord()
jsou vzájemně inverzní funkce, které můžeme používat pro jednoznakové řetezce. chr(i)
očekává celé číslo a vrátí string tvořený znakem s kódem i
. Aby se ten znak zobrazil, musí být definován v použitém fontu. Jinak se zobrazí jen jako kód. Funkce ord(c)
čeká na string obsahující jeden znak a vrátí desítkový kód tohoto znaku ve znakové sadě Unicode.
print(chr(0x20ac)) # Znak euro
print(chr(0x1D120)) # Houslový klíč
print(ord("€"))
c = ord("A")
print(c, chr(c))
print(66, chr(66))
print(ord("F"), "F")
€ 𝄠 8364 65 A 66 B 70 F
Porovnávání a řazení stringů¶
Řetězce se mohou porovnávat pomocí standardních operátorů ==
, !=
, <
, >
, <=
, >=
, které už jsou pro nás dobře známé. Porovnávání se uskutečňuje znak po znaku v pořadí zleva doprava podle kódů znaků, které jsou stejně vzdálené od začátků řetězců. Jakmile znaky na stejných pozicích nebudou shodné, je za větší prohlášen ten text, v němž je znak s větším kódem. Pokud už není co porovnávat, protože jeden ze stringů skončil, za větší bude určen delší.
Poznámka: I když to vypadá velmi podobně tomu, jak děláme lexikografické uspořádání, není to přesně tak. A v případě použití písmen české abecedy nebo nepísmenných znaků můžeme dostat vůbec neočekáváný výsledek. Např. celá sada velkých písmen latinky (bez diakritiky) se nachází před celou sadou stejných malých písmen. To znamená, že libovolné malé písmeno bude v smyslu takového porovnání větší než každé malé. Budete-li chtít řadit texty podle pravidel nějakého jazyka, musíme vytvořit adaptovány algoritmus nebo použít knihovnu, která má pravidla daného jazyka vestavěná.
Doplňte níže několik příkladů, které pomohou vyšetřovat "divné" výsledky porovnání stringů. Případně využijte funkci ord()
, aby bylo zjevně vidět příčiny.
print("země" < "zeli")
print("Země" < "zeli")
print("acd" > 'ac' > "ab" > "a")
print(ord("Z"), ord("z"), ord("e"), ord("ě"))
print(ord("c"), ord("C"), ord("ě"))
s = sorted(["acd","abc","Abc"])
print(s)
False True True 90 122 101 283 99 67 283 ['Abc', 'abc', 'acd']
Příklady¶
- Počet výskytů znaků. Napište funkci, která pro daný string spočte, kolikrát se v něm vyskytuje daný znak. Zatím nepoužívejte žádné metody třídy
str
.
def count_occurrences(text, c):
count = 0
for x in text:
if x == c:
count += 1
return count
assert count_occurrences("abrakadabra", "a") == 5
assert count_occurrences("abrakadabra", "c") == 0
assert count_occurrences("", "a") == 0
- Samohlásky. Samohláskami v latinské abecedě jsou písmena A, E, I, O, U a Y. Jiná písmena si považujme za souhlásky. Napište funkci, který spočítá počet samohlásek v daném textu.
def count_vowels(text):
vowels = "AEIOUYaeiouy"
count = 0
for c in text:
if c in vowels:
count += 1
return count
assert count_vowels("Eighty percent of success is showing up. Woody Allen") == 17
- Morseovka. Implementujte převod textu na morseovku a zpět pomocí slovníku
to_morse(text)
,from_morse(text)
.
MORSE_CODE = {
"A": ".-", "B": "-...", "C": "-.-.", "D": "-..",
"E": ".", "F": "..-.", "G": "--.", "H": "....",
"I": "..", "J": ".---", "K": "-.-", "L": ".-..",
"M": "--", "N": "-.", "O": "---", "P": ".--.",
"Q": "--.-", "R": ".-.", "S": "...", "T": "-",
"U": "..-", "V": "...-", "W": ".--", "X": "-..-",
"Y": "-.--", "Z": "--..", "1": ".----", "2": "..---",
"3": "...--", "4": "....-", "5": ".....", "6": "-....",
"7": "--...", "8": "---..", "9": "----.", "0": "-----",
}
def to_morse(text):
s = ""
for c in text:
if c in MORSE_CODE:
s += MORSE_CODE[c] + " "
else:
s += c
return s
print(to_morse("SOS"))
... --- ...
def from_morse(text):
s = ""
one = ""
for c in text:
if c in ".-":
one += c
elif one in MORSE_CODE.values():
for key in MORSE_CODE:
if MORSE_CODE[key] == one:
s += key
one = ""
else:
s += c
return s
print(from_morse(to_morse("SOS POMOC")))
SOS POMOC
- Palindrom. Palindrom je posloupnost znaků, která se čte stejně pozpátku jako dopředu. Zjistěte, zda zadaný text je palindrom. Nezapomeňte, že mezera se při čtení neprojevuje. Naprogramujte funkci
is_palindrome(string)
, která vrátíTrue
, pokud zadaný string je palindrom, aFalse
, pokud není. K tomu je možné použit funkci z předchozího úkolu.
def is_palindrome(string):
return string == string[ : :-1]
assert is_palindrome("kobylamamalybok")
def is_palindrome(string):
for i in range(len(string)):
if string[i] != string[-i-1]:
return False
return True
assert is_palindrome("kobylamamalybok")
- Diagonála. Napište funkci
diagonal(string, lines_count)
, která vypíše zadáný uživatelem řetězecstring
šikmo dolines_count
řádků:
diagonal("abcdefgh", 2) ->
a c e g
b d f h
diagonal("abcdefgh", 3) ->
a d g
b e h
c f
def diagonal(string, lines_count):
...
diagonal("abcdefgh", 2)
diagonal("abcdefgh", 3)
- Heterogram. Heterogram je slovo, v kterém každý znak se vyskytuje nejvýše jednou. Naprogramujte funkci
is_heterogram(slovo)
, která vracíTrue
neboFalse
jako odpověď na otázku, je-li dané slovo heterogram.
def is_heterogram(string):
return len(string) == len(set(string))
assert is_heterogram("abcdeb") == False
- Bláznivé křížení zvířat. Máme dva seznamy
s
,t
s názvy zvířat. Napište funkcimerge_animals(s, t)
, která vytvoří nový seznam, který bude obsahovat "zkřížené" názvy zvířat tak, že z prvního názvu vezmeme vždy první polovinu a z druhého druhou polovinu. Např.'hroch' a 'tigr' -> 'hrogr'
.
def merge_animals(s, t):
...
assert merge_animals(["hroch","potkan"],["žirafa","orangutan","lev"]) == ['hroafa', 'potgutan']
- Reverse. Napište funkci
reverse(string)
, která vezme textový řetězec a vrátí ho otočený.
def reverse(string):
...
- Periodické řetězce. Budeme říkat, že řetězec má periodu $k$, pokud ho lze vytvořit zřetězením jednoho nebo více opakování jiného řetězce délky $k$. Např. řetězec
"abcabcabcabc"
má periodu 3, protože je tvořen 4 opakováními řetězce"abc"
. Má také periody 6 (dvě opakování"abcabc"
) a 12 (jedno opakování"abcabcabcabc"
). Napište funkci, která určí nejmenší periodu zadaného řetězce.
def find_period(s):
...
assert find_period("abcabcabcabc")==3
assert find_period("abcabcabcabc ")==10