Cvičení č. 14 rozšířené o poznámky ze cvičení a řešení některých příkladů (ZS 2024/25)¶
V minulém díle jste viděli…¶
Textový řetězec (string) je základní datový typ v Pythonu, který představuje posloupnost libovolných znaků.
Se stringy pracujeme pomocí typu str
, což je neměnný (immutable) kontejner.
Stringy zapisujeme pomocí jednoduchých nebo dvojitých uvozovek, případně pomocí trojic jednoduchých nebo dvojitých uvozovek.
s1 = "Potřebuji 'apostrofy'"
s2 = 'Potřebuji "uvozovky"'
s3 = '''Jsem víceřádkový string,
vytvořený pomocí
trojic jednoduchých uvozovek.'''
print(s1)
print(s2)
print(s3)
Potřebuji 'apostrofy' Potřebuji "uvozovky" Jsem víceřádkový string, vytvořený pomocí trojic jednoduchých uvozovek.
Použití escape sekvencí začínajících zpětným lomítkem (\
) umožňuje vkládat do stringů speciální znaky, jako například nový řádek (\n
) nebo uvozovky (\"
).
Python umožňuje převádět stringy na jiné datové typy a zpět.
print(int("1234"))
print(float(-3.5))
print(complex("1+2j"))
print(bool("0"))
print(str("Python"))
print(repr("Python"))
1234 -3.5 (1+2j) True Python 'Python'
# opakovani:
s = "abcdef ahoj!"
# podmínka
c = "a"
if c in s:
print("ano, je tam")
# for-cyklus:
for x in s:
print(x, end = " ")
print("")
for i in range(len(s)):
print(s[i], end = " ")
print("")
# indexace:
print(s[0])
#s[0] = "2" # chyba!
# slicing
print(s[2:4])
# zřetězení
s = "ahoj" + " " + "lidi"
print(s)
s = "20" * 3 + " " + s[1:-3]
s += " A"
print(s)
ano, je tam a b c d e f a h o j ! a b c d e f a h o j ! a cd ahoj lidi 202020 hoj l A
Pro stringy je možné používat základní operace jako testování, iterování, zřetězení, porovnání. Dále je k dispozici indexování a slicing. Porovnávání stringů se provádí znak po znaku podle jejich kódů. Pozor na výsledky porovnání, které mohou být ovlivněny znakovou sadou a velikostí písmen!
Pro zpracování jednotlivých znaků lze použít funkce chr()
a ord()
.
Funkce chr(i)
převádí celé číslo i
na znak, zatímco ord(c)
převádí znak c
na jeho kód v Unicode.
Python nezavádí samostatný datový typ pro znaky, zadávají se jako stringy obsahující pouze jeden znak.
print(chr(0x20ac)) # Znak euro
print(chr(87))
print(ord("€"))
# porovnání:
print("a" < "A") # False
print(ord("a"), ord("A"), ord("Á"))
print(sorted("abhjsHWUVPgcvsdgcdsjkzdg"))
€ W 8364 False 97 65 193 ['H', 'P', 'U', 'V', 'W', 'a', 'b', 'c', 'c', 'd', 'd', 'd', 'g', 'g', 'g', 'h', 'j', 'j', 'k', 's', 's', 's', 'v', 'z']
Textové řetězce (2. část)¶
Metody pro práci se stringy¶
Typ str
v Pythonu poskytuje řadu metod pro běžné operace s textem.
Podrobně se s pojmem metoda seznámíme na konci semestru v tématu o objektově orientovaném programování, ale již při používání jiných typů jsme se s metodami setkali (např. komplexní čísla – metoda complex.conjugate()
nebo seznamy – metoda list.append()
).
Pro připomenutí: metoda je "v podstatě funkce", která provádí akci spojenou s konkrétním objektem.
Při volání metody pro string budeme používat obecnou syntaxi textový_řetězec.název_metody()
, kde textový_řetězec
je určitý objekt typu str
a název_metody
je určitá metoda, kterou chceme použít.
V kulatých závorkách při volání metody navíc můžou být parametry, které daná metoda podporuje.
Řetězcových metod je celá řada. Tyto metody můžeme klasifikovat dle účelu, ke kterému slouží:
- spojování a rozdělování
- ořezávání
- vyhledávání
- nahrazování
- zjišťovací metody
- formátování
Některé z nich dále probereme podrobně a ukážeme základní příklady jejich použití. Detaily o všech metodách třídy str
jsou k dispozici v dokumentaci https://docs.python.org/3/library/stdtypes.html#string-methods.
Poznámka:
Stringy jsou nemodifikovatelná posloupnost, proto žádná z metod typu str
nemodifikuje přímo objekt, na kterém je volána.
Místo toho je "modifikace" stringu vrácena jako nový objekt.
Proto například pokud chceme v proměnné text
nahradit všechny výskyty znaku A
znakem B
, musíme napsat text = text.replace("A", "B")
a ne jen text.replace("A", "B")
.
Pamatujte na to při používání všech metod.
s = [1, 2, 3, 4, 5]
v = s.remove(3)
print(s)
print(v)
[1, 2, 4, 5] None
s = "abcdefabc"
v = s.replace("a", "")
print(s)
print(v)
abcdefabc bcdefbc
Spojování a rozdělování stringů¶
Spojení dvou stringů můžeme provést pomocí operátoru +
.
Pro zřetězení více stringů můžeme místo cyklu použít metodu join
(string.join(container)
):
- String, na kterém metodu voláme, funguje jako oddělovač.
- Kontejner, který předáme metodě jako argument, obsahuje objekty, které chceme spojit.
- Návratovou hodnotou metody je výsledný zřetězený string.
ovoce = ["Jablko", "Hruška", "Meruňka"]
s1 = ", ".join(ovoce) # Jako oddělovač použijeme čárku s mezerou
s2 = "".join(ovoce) # Jako oddělovač použijeme prázdný řetězec
s3 = "; ".join("Jablko") # Pokud jako argument použijeme string, oddělovač se vloží mezi všechny jeho znaky
s3 = " ".join("Jablko")
print(s1)
print(s2)
print(s3)
Jablko, Hruška, Meruňka JablkoHruškaMeruňka J a b l k o
Pokud naopak chceme string rozdělit na části podle určitého oddělovače, můžeme použít některou z následujících metod:
split
(str.split(sep=None, maxsplit=-1)
) – výsledkem je seznam stringů, přičemž každý je částí původního stringu v odpovídajícím pořadí a oddělovače ve výsledném seznamu chybí- parametr
sep
určuje oddělovač (separator) – pokud není zadaný, dělí se dle všech bílých znaků (např. mezera nebo\n
) - parametr
maxsplit
určuje, jaký maximální počet dělení se má provést (hodnota-1
znamená bez limitu)
- parametr
rsplit
(str.rsplit(sep=None, maxsplit=-1)
) – funguje stejně jakosplit
, ale prohledává řetězec od koncesplitlines
(str.splitlines(keepends=False)
) – rozdělí string na jednotlivé řádky (oddělovačem je znak\n
) a vrátí seznam stringů, přičemž každý string buď obsahuje konec řádku (pokudkeepends=True
) nebo neobsahuje konec řádku (pokudkeepends=False
)
list1 = "Jablko a hruška a meruňka".split(" a ")
list2 = "Jablko,,hruška,,meruňka".split(",") # Separátory se neslučují
list3 = "Jablko a hruška\na meruňka".split() # Používají se výchozí hodnoty parametrů
list4 = "Jablko,,hruška,,meruňka".split(";") # Separátor není nalezen
list5 = "Jablko a hruška a meruňka".split(" a ", 1) # Určujeme maximální počet použití separátoru
list6 = "Jablko a hruška a meruňka".rsplit(" a ", 1) # Začínáme zprava
print(list1, list2, list3, list4, list5, list6, sep="\n")
['Jablko', 'hruška', 'meruňka'] ['Jablko', '', 'hruška', '', 'meruňka'] ['Jablko', 'a', 'hruška', 'a', 'meruňka'] ['Jablko,,hruška,,meruňka'] ['Jablko', 'hruška a meruňka'] ['Jablko a hruška', 'meruňka']
"ahoj lidi\t jablko\n\n\nhruska".split()
['ahoj', 'lidi', 'jablko', 'hruska']
"ahoj lidi\t jablko\n\n\nhruska".splitlines(keepends=True)
['ahoj lidi\t jablko\n', '\n', '\n', 'hruska']
partition
(str.partition(sep)
)- pokud string obsahuje zadaný oddělovač (parametr
sep
), vrátí trojici obsahující string před oddělovačem, oddělovač, a string za oddělovačem - pokud string neobsahuje zadaný oddělovač, vrátí trojici obsahující původní string a dva prázdné stringy
- pokud string obsahuje zadaný oddělovač (parametr
rpartition
(str.rpartition(sep)
)- pokud string obsahuje zadaný oddělovač (parametr
sep
), vrátí trojici obsahující string před oddělovačem, oddělovač, a string za oddělovačem - pokud string neobsahuje zadaný oddělovač, vrátí trojici obsahující dva prázdné stringy a původní string
- pokud string obsahuje zadaný oddělovač (parametr
ntice1 = "Jablko a hruška a meruňka".partition(" a ")
ntice2 = "Jablko a hruška a meruňka".partition(" x ") # Oddělovač není nalezen
ntice3 = "Jablko a hruška a meruňka".rpartition(" a ") # Hledáme oddělovač zprava
ntice4 = "Jablko a hruška a meruňka".rpartition(" x ") # Hledáme zprava, oddělovač není nalezen
print(ntice1, ntice2, ntice3, ntice4, sep="\n")
('Jablko', ' a ', 'hruška a meruňka') ('Jablko a hruška a meruňka', '', '') ('Jablko a hruška', ' a ', 'meruňka') ('', '', 'Jablko a hruška a meruňka')
Tip: Pro každou metodu typu str
si můžete zobrazit oficiální nápovědu – v ní ale ignorujte parametr self
(tím se budeme zabývat podrobně na konci semestru). Po napsání části str.
můžete stisknout klávesu Tab a nechat si doplnit všechny existující metody.
help(str.split)
Help on method_descriptor: split(self, /, sep=None, maxsplit=-1) unbound builtins.str method Return a list of the substrings in the string, using sep as the separator string. sep The separator used to split the string. When set to None (the default value), will split on any whitespace character (including \n \r \t \f and spaces) and will discard empty strings from the result. maxsplit Maximum number of splits. -1 (the default value) means no limit. Splitting starts at the front of the string and works to the end. Note, str.split() is mainly useful for data that has been intentionally delimited. With natural text that includes punctuation, consider using the regular expression module.
Zjišťovací metody¶
Typ str
nabízí mnoho metod bez parametrů, které vracejí hodnoty True
/False
podle toho, jestli daný string splňuje určité vlastnosti.
Metoda | Krátký popis |
---|---|
islower |
Vrací True , je-li ve stringu alespoň jedno písmeno a všechna písmena jsou malá. Znaky, které nejsou písmeny, výsledek neovlivní. |
isupper |
Vrací True , je-li ve stringu alespoň jedno písmeno a všechna písmena jsou velká. Znaky, které nejsou písmeny, výsledek neovlivní. |
istitle |
Vrací True , je-li ve stringu alespoň jedno písmeno a mají-li ve stringu všechna slova první písmeno velké a ostatní malá. Znaky, které nejsou písmeny, výsledek neovlivní. |
isalpha |
Vrací True , je-li string neprázdný a všechny jeho znaky jsou v sadě Unicode považovány za písmena. |
isdecimal |
Vrací True , je-li string neprázdný a všechny jeho znaky mohou být použity pro zápis čísel o základu 10. |
isdigit |
Vrací True , je-li string neprázdný a všechny jeho znaky jsou v sadě Unicode považovány za číslice. Vedle běžných číslic a číslic zapsaných jako indexy či exponenty sem patří i číslice dalších jazyků – např. arabsko-indické. |
isnumeric |
Vrací True , je-li string neprázdný a všechny jeho znaky jsou v sadě Unicode považovány za reprezentanty čísel. Sem patří vedle číslic i řada dalších znaků reprezentujících některé zlomky, římské číslice a jiné symboly. Platí isdecimal() ⊆ isdigit() ⊆ isnumeric() . |
isalnum |
Vrací True , je-li string neprázdný a všechny znaky představují písmena, číslice či čísla. Za alfanumerický je znak c považován v případě, vrací-li True alespoň jedna z metod c.isalpha() , c.isdecimal() , c.isdigit() , c.isnumeric() . |
isspace |
Vrací True , je-li string neprázdný a všechny jeho znaky jsou v sadě Unicode klasifikovány jako bílé znaky. |
isprintable |
Vrací True , je-li string prázdný, nebo obsahuje pouze tisknutelné znaky. Za netisknutelné znaky jsou mimo jiné považovány všechny bílé znaky s výjimkou obyčejné mezery (tedy naříklad pevná mezera '\xA0' je netisknutelný znak). |
isascii |
Vrací True , je-li string prázdný, nebo mají všechny jeho znaky kód menší nebo roven 255 (0x7F ). |
isidentifier |
Vrací True , je-li string platným identifikátorem podle pravidel Pythonu. |
# Write your exercise code here
print("abc def".islower())
print("A Q".isupper(),"\n")
print("abc def".isalpha(),"\n")
print("162".isdecimal())
print("16.2".isdecimal())
print("16.2".isnumeric(),"\n")
print("abc def".isprintable())
print("abc\tdef".isprintable())
True True False True False False True False
Vyhledávání podstringů¶
Pro vyhledávání podřetězců má typ str
v Pythonu celou sadu metod.
Všechny tyto metody mají tři parametry: Povinným argumentem je hledaný podstring, volitelnými parametry start
a end
lze omezit hledání na podřetězec v rozsahu slice [start:end]
.
Parametry start
a end
nelze předat pojmenovaným způsobem, proto potřebujete-li zadat parametr end
, musíte zadat i start
.
Metody | Krátký popis |
---|---|
count |
Vrací počet nepřekrývajících se výskytů zadaného podstringu. |
find , rfind |
Vracejí pozici počátku prvního výskytu zadaného podstringu. Není-li podstring nalezen, vrátí -1 . Metoda rfind prohledává zprava. |
index , rindex |
Pracují stejně jako metody find , resp. rfind . Liší se pouze tím, že nenajdou-li hledaný řetězec, vyvolají ValueError . |
startswith , endswith |
Vracejí True v případě, začíná-li (resp. končí-li) prohledávaný řetězec zadaným podstringem. Prvním argumentem může být i n-tice stringů. |
Příklady použití těchto metod zkuste vymyslet samostatně.
# Write your exercise code here
print("babab bab bababa".count("bab"))
print("babab bab bababa".count("bab", 0, 4))
print("babab bab bababa".startswith("bab"))
3 1 True
Metody nahrazování¶
Často potřebujeme nejen zkontrolovat, jestli string obsahuje zadaný podřetězec, ale také ho nahradit nějakým jiným stringem.
V nejjednodušším případě k tomu stačí použit metodu replace
:
replace(old, new, count=-1)
:- parametr
old
představuje string, který hledáme - parametr
new
představuje náhradu za hledaný string - parametr
count
určuje maximální počet nahrazení (hodnota-1
znamená bez limitu)
- parametr
s1 = "Ve slově standart se na konci nepíše t, ale d!"
print(s1.replace("t", "d"))
print(s1.replace("t", "d", 2))
print(s1)
Ve slově sdandard se na konci nepíše d, ale d! Ve slově sdandard se na konci nepíše t, ale d! Ve slově standart se na konci nepíše t, ale d!
Zmiňme ještě jednu nahrazovací metodu expandtabs(tabsize=8)
, která vrací kopii stringu, v níž jsou tabulátory (znak \t
) nahrazeny sadou mezer tak, aby to odpovídalo zadané velikosti kroku tabulátoru. Vyzkoušejte na příkladu:
print("01\t012\t0123\t01234".expandtabs())
print("01\t012\t0123\t01234".expandtabs(4))
01 012 0123 01234 01 012 0123 01234
Ořezávání stringů¶
Při práci se vstupem od uživatele je často potřeba vstup zkontrolovat a případně upravit. Jedním z častých problémů jsou nadbytečné mezery (nebo obecně bílé znaky) na začátku nebo na konci řetězce. Tyto přebytečné znaky mohou způsobovat chyby při ukládání dat, vyhledávání, řazení nebo při kontrole unikátnosti. K odstranění těchto znaků je možné použít jednu z následujících metod:
lstrip
(str.lstrip(chars=None)
) – odstraňuje zadané znaky ze začátku stringu (zleva)rstrip
(str.rstrip(chars=None)
) – odstraňuje zadané znaky z konce stringu (zprava)strip
(str.strip(chars=None)
) – odstraňuje zadané znaky ze začátku i z konce stringu
Pokud parametr chars
není zadaný, metody odstraní všechny bílé znaky (např. mezera, tabulátor nebo \n
).
s1 = " Nechci bílé znaky před ani za textem! \n ".strip()
s2 = " Nechci bílé znaky před textem! \n ".lstrip()
s3 = " Nechci bílé znaky za textem! \n ".rstrip()
s4 = "* Nechci * před ani za textem!****".strip("*")
s5 = "*--Nechci * ani - za textem!**---".rstrip("*-")
print(s1, s2, s3, s4, s5, sep="\n")
Nechci bílé znaky před ani za textem! Nechci bílé znaky před textem! Nechci bílé znaky za textem! Nechci * před ani za textem! *--Nechci * ani - za textem!
Všimněte si, že metody lstrip
a rstrip
neodebírají prefix, resp. suffix – parametr chars
má význam množiny znaků, nikoliv podposloupnosti.
Pokud chcete odebrat předponu nebo koncovku, můžete využít metody removeprefix
a removesuffix
.
s5 = "*--Nechci * ani - za textem!**---".removesuffix("*---")
print(s5)
*--Nechci * ani - za textem!*
Metody pro jednoduché formátování¶
Pro základní změnu velikosti písmen Python nabízí několik jednoduchých metod bez parametrů. Znaky, které nejsou považovány za písmena, nejsou těmito metodami ovlivněny.
Metoda | Krátký popis |
---|---|
lower |
Vrátí nový string, ve kterém jsou všechna písmena převedena na malá písmena. |
upper |
Vrátí nový string, ve kterém jsou všechna písmena převedena na velká písmena. |
capitalize |
Vrátí nový string s prvním písmenem velkým a ostatními písmeny malými. |
title |
Vrátí nový string, kde je první písmeno každého slova velké a ostatní písmena malá. Slova jsou definována jako skupiny po sobě jdoucích písmen. Tato definice funguje ve většině případů, ale má své limity (např. apostrofy jsou považovány za oddělovače slov). |
s1 = "Text z malých písmen, VELKÝCH PÍSMEN a čísla 42."
print(s1.lower(), s1.upper(), s1.capitalize(), s1.title(), sep="\n")
s2 = "they're bill's friends from the UK"
print(s2.title())
text z malých písmen, velkých písmen a čísla 42. TEXT Z MALÝCH PÍSMEN, VELKÝCH PÍSMEN A ČÍSLA 42. Text z malých písmen, velkých písmen a čísla 42. Text Z Malých Písmen, Velkých Písmen A Čísla 42. They'Re Bill'S Friends From The Uk
Pro zlepšení čitelnosti delších textů může být potřeba zarovnat text doleva, doprava, nebo na střed.
K tomu slouží metody ljust
, rjust
a center
.
Povinným pozičním parametrem všech těchto metod je požadovaná délka výsledného stringu.
Text bude podle typu zarovnání standardně doplněn mezerami na začátku, na konci nebo z obou stran, aby dosáhl požadované délky.
Pomocí druhého nepovinného parametru můžeme určit, jaký znak se má použít k doplnění stringu místo mezery.
print("|", "vlevo".ljust(20), "|", "uprostřed".center(20), "|", "vpravo".rjust(20), "|")
print("|", "jiny text".ljust(20), "|", "gjf".center(20), "|", "jjf ggyug".rjust(20), "|")
print ("Ahoj!".center(40, '-'))
| vlevo | uprostřed | vpravo | | jiny text | gjf | jjf ggyug | -----------------Ahoj!------------------
Formátování řetězců¶
Doposud jsme v případech, kdy jsme chtěli vytvořit "hezký" výstup pro uživatele, museli použít funkci print
a vhodně zvolit objekty k zobrazení.
Například, pokud jsme chtěli vypsat číselné hodnoty společně s krátkým vysvětlením, museli jsme funkci print
předat "mix" proměnných a stringů:
hodiny = 2
minuty = hodiny * 60
print("vysledek:", hodiny, "hod je", minuty, "min")
vysledek: 2 hod je 120 min
U delšího nebo složitějšího textu však tento přístup není praktický.
Navíc někdy potřebujeme výstup uložit pro další zpracování, nejen zobrazit pomocí funkce print
.
Mohli bychom sice číselné hodnoty převést na string a potom stringy zřetězit, Python ale nabízí elegantnější způsob formátování.
Pro znázornění si představte textovou šablonu s prázdnými místy, která později vyplníme konkrétními hodnotami:
Mil[ý/á] _______,
Váš výsledek 1. testu ZPRO je __________ bodů.
S pozdravem
_________
Aby Python věděl, které hodnoty umístit do kterých vynechaných míst, je potřeba jednotlivá vynechaná místa v šabloně nějak jednoznačně označit. K tomu se používají složené závorky a identifikátory:
Mil{y_a} {osloveni},
Váš výsledek 1. testu ZPRO je {soucet} bodů.
S pozdravem,
{podpis}.
Takovou textovou šablonu můžeme použít jako tzv. formátovací řetězec neboli f-string (anglicky formatted string literal).
Formátovací řetězec se vytváří podobně jako obyčejný řetězec s tím rozdílem, že před první uvozovkou nebo apostrofem musíme přidat předponu f
nebo F
.
Pro uvedený příklad můžeme vytvořit jednoduchý program:
x = 6 + 5
string = f"Vysledek prikladu je {x + 34}."
print(string)
string = f"Hodnota výrazu je {x / 3 + 34}."
print(string)
string = f"Hodnota výrazu je {x / 3 + 34:.2f}."
print(string)
Vysledek prikladu je 45. Hodnota výrazu je 37.666666666666664. Hodnota výrazu je 37.67.
y_a = "á"
osloveni = "Žofie"
ukol1 = 25
ukol2 = 40
ukol3 = 20
soucet = ukol1 + ukol2 + ukol3
podpis = "Váš cvičící"
vystup = f"""
Mil{y_a} {osloveni},
Váš výsledek 1. testu ZPRO je {soucet} bodů.
S pozdravem,
{podpis}
"""
print(vystup)
Milá Žofie, Váš výsledek 1. testu ZPRO je 85 bodů. S pozdravem, Váš cvičící
Uvnitř složených závorek lze namísto identifikátorů proměnných použít jakékoli výrazy, volání funkcí apod.
Shrňme tedy základy práce s f-stringy, včetně několika dalších možností:
- Pro f-stringy platí stejná pravidla jako pro obyčejné textové řetězce. Mohou je ohraničovat jednoduché, dvojité uvozovky nebo jejich trojice. Liší se pouze tím, že před úvodním uvozováním píšeme předponu
f
neboF
. - F-stringy mohou obsahovat nahrazovací pole s výrazy, jejichž hodnota se má dosadit do výsledného stringu.
- Výrazy v nahrazovacích polích jsou vyhodnocovány zleva doprava, což má vliv pouze tehdy, pokud některé z výrazu mají vedlejší efekty.
- F-stringy můžeme vytvořit jako zřetězení (součet) několika stringů, ale každý spojovaný řetězec by měl být f-string (jinak se nahrazovací pole v součtu neuplatní a budou brána jako běžný text).
- Při ladění programu může být užitečné, pokud výraz v nahrazovacím poli zakončíme znakem
=
, což způsobí, že do stringu se vloží samotný zápis výrazu (včetně případných mezer a závěrečného rovnítka) a teprve za něj jeho výsledná hodnota.
from math import pi
r = 4
print(f"Obvod kruhu o poloměru {r =} je {2 * pi * r }")
Obvod kruhu o poloměru r =4 je 25.132741228718345
string = r"ahoj\"t\\ahoj"
print(string)
ahoj\"t\\ahoj
Poznámka:
Předponu f
/F
lze kombinovat s předponou r
/R
, která označuje surový literál (anglicky raw literal). V surovém literálu nejsou podporovány escape sekvence, každý znak je interpretován doslovně. Výjimkou jsou pouze uvozovky, které musíme nadále zadávat se zpětným lomítkem. Surový řetězcový literál se hodí při práci s cestami k souborům nebo při zadávání regulárních výrazů.
Někdy se může stát, že jednu textovou šablonu chceme použít několikrát.
V takovém případě nám f-string již nepomůže, protože v něm se "prázdná místa" doplňují automaticky a hned.
Místo toho můžeme použít metodu format
pro obyčejný string.
Poznámka:
Historicky jsou f-stringy novější vlastností Pythonu, která byla zavedena až ve verzi 3.6. Naopak metoda format
se objevila dříve již ve verzi Python 3. Pravidla pro formátování nahrazovacích polí pro f-stringy jsou fakticky převzatá z metody format
.
Hlavička metody format
má tvar format(*args, **kwargs)
, což znamená, že hodnoty dosazované do stringu můžeme specifikovat buď pomocí jejich pořadí, nebo jejich názvem.
Názvy vkládaných hodnot nemusí být platné identifikátory, což činí metodu format
obecnější než f-stringy.
s1 = "{} krát {} je {}.".format(2, 3, 2 * 3)
print(s1)
s2 = "Ahoj, jsem {jmeno}. A moje oblibené číslo je {cislo}."
print(s2.format(cislo=7, jmeno="Matěj"))
print(s2.format(cislo=42, jmeno="divný člověk"))
#print(s2.format("Žofie", 3)) # KeyError: není možné dosadit nepojmenovaný argument do pojmenovaného místa
2 krát 3 je 6. Ahoj, jsem Matěj. A moje oblibené číslo je 7. Ahoj, jsem divný člověk. A moje oblibené číslo je 42.
Příklady¶
- Silné heslo. Heslo budeme označovat jako silné, jsou-li splněná následující kritéria:
- Heslo obsahuje malá písmena latinské abecedy.
- Heslo obsahuje velká písmena latinské abecedy.
- Heslo obsahuje číslice.
- Heslo obsahuje alespoň jeden ze znaků
! " # $ % & ' ( ) * +
. - Délka hesla není menší než 8 znaků.
Napište funkci, která zjistí (a ve vhodné formě vrátí), které z těchto pěti kritérií silného hesla jsou pro použité heslo splněny.
def strong_password(passwd):
a = b = c = d = e = False
for znak in passwd:
if znak.islower():
a = True
elif znak.isupper():
b = True
elif znak.isdecimal():
c = True
elif znak in "!\"#$%&'()*+":
d = True
if len(passwd) >= 8:
e = True
return (a, b, c, d, e, a & b & c & d & e)
print(strong_password("Moje8Heslo ")) # splňuje všechna kriteria
(True, True, True, False, True, False)
def strong_password(passwd):
vysledek = {"a": False, "b": False, "c": False, "d": False, "e": False }
for znak in passwd:
if znak.islower():
vysledek["a"] = True
elif znak.isupper():
vysledek["b"] = True
elif znak.isdecimal():
vysledek["c"] = True
elif znak in "!\"#$%&'()*+":
vysledek["d"] = True
if len(passwd) >= 8:
vysledek["e"] = True
return vysledek
print(strong_password("Moje8Heslo'")) # splňuje všechna kriteria
{'a': True, 'b': True, 'c': True, 'd': True, 'e': True}
- Anagramy. Slovo je anagramem jiného slova, když ho lze získat přeuspořádáním jeho písmen. Napište funkci
anagrams(word1, word2)
, která vrátíTrue
, pokud jsou tato dvě slova anagramy, aFalse
, pokud nejsou.
string = "abcdabcdda"
print(string.count("a"))
l = sorted(string)
print(l)
3 ['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd', 'd']
def anagrams(str1, str2):
return sorted(str1) == sorted(str2)
def anagrams(str1, str2):
for x in set(str1+str2):
if str1.count(x) != str2.count(x):
return False
return True
assert anagrams("reklama", "makrela")
assert anagrams("reklama", "marekll") == False
- Iniciály. Napište program, který se zeptá uživatele na jméno, pak na příjmení a potom vypíše iniciály – první písmena zadaných jmen. Iniciály jsou vždy velkými písmeny (i kdyby byl uživatel líný mačkat
Shift
). Možné náhodné mezery na začátku jména nebo příjmení také odstraňte. Pro převod zadaných jmén na iniciály použijte pomocnou funkciget_initials(name, surname)
.
def get_initials(name, surname):
name = name.lstrip()
surname = surname.lstrip()
initials = name[0] + surname[0]
return initials.upper()
get_initials(" jan ", " novák")
'JN'
- Frekvenční analýza. Napište funkci
freq_analysis(text)
, která spočítá výskyt jednotlivých písmen (znaků) ve vstupním textu a vrátí výsledek jako slovník nebo jako seznam dvojic (znak, počet výskytů). Vypište znaky s počty jejich výskytů setříděné sestupně podle počtu výskytů.
def freq_analysis(text):
dictionary = {}
text = text.lower()
for c in set(text):
if c.isalnum():
dictionary[c]=text.count(c)
return dictionary
d = freq_analysis("All the world is a stage and all the men and women merely players.")
...
Ellipsis
def freq_analysis(text):
dictionary = {}
text = text.lower()
for c in text:
if c.isalnum():
if c in dict:
dictionary[c] += 1
else:
dictionary[c] = 1
return dict
d = freq_analysis("All the world is a stage and all the men and women merely players.")
...
- Délka slov. Naprogramujte funkci, která zjistí délku každého slova v textu. Předpokládejme, že slova jsou oddělená pomocí obyčejných mezer (možná několika za sebou).
def word_lengths(text):
words = text.split()
word_lengths = []
for word in words:
word_lengths.append(len(word))
return word_lengths
assert word_lengths(" Toto je příklad textu s různě dlouhými slovy. ") == [4, 2, 7, 5, 1, 5, 8, 6]
- Frekvenční analýza slov. Napište funkci
freq_analysis(text)
, která spočítá výskytů jednotlivých slov ve vstupním textu a vrátí výsledek jako slovník nebo jako seznam dvojic (slovo, počet výskytů). Vypište slova s počty jejich výskytů setříděné vzestupně podle abecedy.
def freq_analysis(text):
...
d = freq_analysis("This is a test. This is only a test, not a real situation.")
...
- Caesarova šifra. Vytvořte si funkci, která zrealizuje šifrování algoritmem Caesarové šifry. To šifrování spočívá v posouvání každého písmena řetězce o určitý počet znaků dle abecedy. Například slovo
"Ahoj"
se s posunem 1 převede na"Bipk"
. Ten posun – klič šifry – povolte vybrat uživateli. Jak by se naprogramovala funkce pro dešifrování?
def caesar(text, shift):
...
a = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"
assert caesar(a,12) == "mnopqrstuvwxyzabcdefghijkl MNOPQRSTUVWXYZABCDEFGHIJKL"
b = "All the world is a stage; And all the men and women merely players."
assert caesar(b, -2) == "Yjj rfc umpjb gq y qryec; Ylb yjj rfc kcl ylb umkcl kcpcjw njywcpq."
assert caesar(b, 26) == b
assert caesar(caesar(b,15), -15) == b
- Kryptoanalýza Caesarovy šifry. Caesarovu šifru lze velmi lehko vyluštit (tj. zjistit neznámý posun – tajný klíč). Zkuste naprogramovat dvě funkce, první implementuje tzv. metodu hrubé sily, druhá způsob frekvenční analýzy.
print(caesar("Ask me, how to "))
def try_caesar(text):
...
try_caesar("Clguba vf n irel hfrshy cebtenzzvat ynathntr. Naq ubj fvzcyr vg vf... V ybir vg!")
def caesar_frequency_analysis(text):
...
caesar_frequency_analysis("Clguba vf n irel hfrshy cebtenzzvat ynathntr. Naq ubj fvzcyr vg vf... V ybir vg!")