previous up next hi end end

6. Řetězce

  1. Složený datový typ
  2. Úseky řetězce
  3. Délka řetězce
  4. Řetězce jsou neměnitelné
  5. Operace s řetězci
  6. Modul 'string'
  7. Smyčka 'while' a 'for'
  8. Příkaz 'break'
  9. Příkaz 'continue'
  10. Operátor 'in' a 'not in'
  11. Porovnávání řetězců
  12. Použití metod
  13. Sestavení funkce 'find'
  14. Formátování řetězců I
  15. Formátování řetězců II
  16. Formátování řetězců III
  17. Dokumentační řetězce
  18. Glosář
  19. Cvičení

6.1 Složený datový typ

Řetězce (strings) jsou neměnitelné sekvence znaků Unicode, vymezené uvozovkami - jednoduchými, dvojitými či trojitými.
Výraz "bim" "bam" je automaticky konvertován na "bim bam".

Pořadí znaku v řetězci je interně indexováno zleva i zprava, neboli je vyjádřeno pořadovým číslem, které zleva začíná nulou.

Při indexování v opačném směru začíná indexování zápornou jedničkou (-1) na posledním místě řetězce vpravo. Hranaté závorky slouží jako operátor, který vybere indexem určený znak z řetězce.

>>> tuto = "Hello World"

>>> print(tuto[1])
e
>>> print(tuto[-1])
d

6.2 Úseky řetězce

Část řetězce se nazývá úsek (slice). Výběr úseku se provádí úsekovým operátorem. Operátor [n:m] vrací úsek řetězce od znaku n včetně po znak před m. :

>>> s = "Peter, Paul, and Mary"
>>> print(s[0:5] )                    # od 0 po 4 včetně (před 5)
Peter
>>> print(s[7:11])                    # od 7 po 10 včetně (před 11)
Paul
>>> print(s[17:21])
Mary

Vynecháme-li první index (před dvojtečkou), začíná úsek na počátku řetězce. Vynecháme-li druhý index, úsek jde až ke konci řetězce. Takže:

>>> fruit = "banana"
>>> fruit[:3]                         # od 0 po 2 včetně
'ban'
>>> fruit[3:]                         # od 3 do konce
'ana'

Výběr úseku se zadaným odstupem prvků zařídíme úsekovým operátorem se třemi parametry [m:n:k]. Ten je vždy implicitně přítomný s krokem k=1.

>>> tuto = "buttons"
>>> tuto[::2]                         # k = 2 
'btos'
>>> print(tuto[::-2])                 # funkce print "očistí" výstup
sotb

Operátor [:] vrací celý řetězec, operátor [::-1] vrací obrácené pořadí řetězce, číslo -1 je třetím parametrem k.

>>> tuto[:]
buttons
>>> tuto[::-1]
snottub
>>> tuto[1:6:2]
'utn'

6.3 Délka řetězce

Funkce len vrací počet znaků v řetězci:

>>> fruit = "banana"
>>> len(fruit)
6

Ve snaze získat poslední písmeno řetězce bychom mohli být v pokušení zkusit něco jako:

>>> délka = len(fruit)
>>> last = fruit[délka]
IndexError: string index out of range
>>> last = fruit[délka-1]
a

6.4 Řetězce jsou neměnitelné

Může být lákavé použít výběrový operátor [] na levé straně přiřazení se záměrem změnit znak v řetězci. Například:

greeting = "Hello, world!"
greeting[0] ='J'        # chyba!
print(greeting)

Místo výstupu Jello, world!, tento kód způsobí chybu při běhu programu: TypeError: 'str' object doesn´t support item assignment.

Řetězce jsou neměnitelné, což znamená, že existující řetězec nelze změnit. Jediná věc, kterou lze udělat, je vytvořit nový řetězec, který je variací původního:

greeting = "Hello, world!"
new_greeting = greeting[:5] + " all" + greeting[6:]
print(new_greeting)
'Hello all world!'

Řešením je zřetězení vložené části s úseky řetězce greeting. Tato operace nemá žádný vliv na původní řetězec.


6.5 Operace s řetězci

6.5.1 Společné operace pro řetězce, entice a seznamy

Obecně vzato, na řetězcích nelze provádět matematické operace. Následující výrazy nejsou přípustné :

"uno" - 1   "Hello / 123   "duo" * "Hello"   "15" + 2

Operátor + však s řetězci pracovat umí, i když jinak, než bychom očekávali. Pro řetězce, entice a seznamy představuje operátor + příkaz zřetězení (concatenation), což je spojení dvou operandů jejich připojením těsně k sobě. Například:

>>> "Chléb " + " a hry" 
Chléb a hry
>>> 1, 2, 3, + 4, 5, 6,    # oba operandy jsou entice
(1, 2, 3, 4, 5, 6)
>>> 1, 2, 3 + 4, 5, 6      
(1, 2, 7, 5, 6)            # spojení neúplných entic
>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]

Operátor * rovněž pracuje s řetězci, enticemi i seznamy, způsobuje jejich zmnožení. Jeden z operandů musí být sekvence, druhým operandem musí být celé číslo, například:

>>> 3 * "bla " == "bla " * 3 == "bla bla bla "
True
>>> (1, 2, 3) * 3              jen v závorkách!
(1, 2, 3, 1, 2, 3, 1, 2, 3)
>>> [1, 2, 3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]

6.5.2 Volně přístupné metody pro řetězce

Kromě společných procedur pro řetězce a seznamy existuje také velké množství vestavěných metod, speciálně určených pro řetězce, které většinou evokujeme sestavou  'řetězec'.metoda():

  capitalize, casefold, center, count, encode, endswith, expandtabs,
  find, format, format_map, index, isalnum, isalpha, isdecimal,
  isdigit, isidentifier, islower, isnumeric, isprintable, isspace,
  istitle, isupper, join, ljust, lower, lstrip, maketrans, partition,
  replace, rfind, rindex, rjust, rpartition, rsplit, rstrip,
  split, splitlines, startswith, strip, swapcase, title, translate,
  upper, zfill

Metody join a split jsou popsány v Kap. 9.1.


6.5.3 Zdroje informací

Potřebné parametry při volání jednotlivých metod naleznete na stránce String Methods, případně lze číst dokumentační řetězec z definice metody příkazem (například):

>>> print( "".find.__doc__)                  # ověřte si to

V prostředí PyScripter se tyto termíny zobrazují jako nápověda včetně požadované skladby a stručného popisu:

pic

Z výše uvedeného obrázku je patrné, že pro objekt s = "Růžový kavalír" má být tečkovou notací volána nějaká metoda. Tuto metodu lze zapsat do konzoly nebo vybrat z automaticky otevřeného seznamu.


6.6 Modul 'string'

Modul string obsahuje další užitečné objekty pro manipulaci s řetězci. Jako obvykle, modul musíme importovat dřív než jej použijeme:

>>> import  string

Obsah modulu zjistíme vestavěnou fcí dir se jménem modulu jako argument:

>>> dir(string)
čímž dostaneme seznam atributů:

[ 'ascii_letters', ascii_lowercase', ascii_uppercase', digits', hexdigits', 'octdigits', printable', punctuation', 'whitespace' ]

a specielních metod:

['Formatter', 'Template', '_TemplateMetaclass', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__','__package__', '_re', '__spec__', '_sentinel_dict', '_string', 'capwords']

Udělejte si průzkum a sami si zjistěte, co jednotlivé atributy vracejí:

>>> string.digits
'0123456789'

>>> string.punctuation
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'

>>> string.whitespace
' \t\n\r\x0b\x0c'                escape sekvence pro whitespace

Znaky whitespace posouvají kurzor, aniž by se cokoli tisklo. Vytvářejí prázdné místo mezi viditelnými znaky.

Konstanty lze s výhodou použít v různých ověřovacích funkcích, například:

def is_lower(ch):
    return string.ascii_lowercase.find(ch) != -1

Nutno si uvědomit, že tato funkce neodpovídá na otázku, zda zkoumané písmeno je velké či malé ale zda patří do sady ascii_lowercase (kde se písmeno "ch" nevyskytuje - stejně jako česká písmena s diakritikou).

>>> is_lower("ch")
False

Metoda string.capwords(str [, sep=None]) rozdělí řetězec na jednotlivá slova (podle zadaného separátoru), počáteční písmena nahradí velkými a znovu spojí jednotlivá slova do jednoho řetězce. Použije-li se jako separátor znak, který není v původním řetězci obsažen, metoda vrátí řetězec s malými písmeny. Bez separátoru odstraní přebytečné mezery

>>> string.capwords("Honolulu  ", "o")
'HoNoLulu  '
>>> string.capwords("    Hono Lu  lU", "čau")
'    hono lu  lu'
>>> string.capwords("  Honolulu    ")
'Honolulu'

6.7 Smyčka 'while' a 'for'

Opakovaný výpočet pro jednotlivé elementy řetězce lze s výhodou provést pomocí smyčky while (viz 4.1):

fruit = "banana" 
index = 0                              # počáteční stav počítadla
while index  <  len(fruit):            # podmínka
    letter = fruit[index]
    print(letter, end=" ")
    index = index + 1                  # změna stavu počítadla
========== RESTART: F:\Codetest\HowTo\trump.py ==========
b a n a n a 
>>> 

Tato smyčka prochází řetězcem a vytiskne každé písmeno. Podmínka smyčky je index < len(fruit), protože index počíná nulou a jeho maximální hodnota je len(fruit)-1.

Komfortnějším nástrojem k procházení (traverzování) iterovatelným objektem je smyčka for:

for char in fruit:
    print(char, end=" ")

Na rozdíl od smyčky while ... používá smyčka for ... k procházení objektem interní objekt, zvaný iterátor - viz kap. 4.7.

Následující příklad ukazuje použití zřetězení (concatenation) a smyčku for pro tvorbu abecedních řad. Abecedním je míněno uspořádání prvků řady či seznamu podle abecedy. Například, v knize Roberta McCloskeyho: Uvolněte cestu pro káčata se kachňata jmenují: Jack, Kack, Lack, Mack, Nack, Ouack, Pack a Quack. Tato smyčka vydá jejich jména v pořadí:

prefixes = "JKLMNOPQ"
suffix = "ack"

for letter in prefixes:
    print(letter + suffix, end=" ")

Výstup programu je tento:

Jack  Kack  Lack  Mack  Nack  Oack  Pack  Qack

V pořádku to úplně není, protože Ouack a Quack nejsou zapsáni správně. Tuto chybu napravíme v rámci cvičení 6.19.1.


6.8 Příkaz 'break'

Při splnění podmínky ukončí příkaz break provádění smyčky. Tento příkaz lze použít u smyček for  i  while:

for letter in "Python":
    if letter == "h":
        break
    print("Current Letter: ", letter)
Current Letter:  P
Current Letter:  y
Current Letter:  t

nebo:

var = 8
while var > 0:
    print("Current var. value: ", var)
    var = var - 1	
    if var == 5:
        break
print("Adieu!")
Current var. value:  8
Current var. value:  7
Current var. value:  6
Adieu!

6.9 Příkaz 'continue'

Při splnění podmínky přeruší příkaz continue provádění smyčky a její výpočet pokračuje dalším elementem sekvence. Tento příkaz lze použít u smyček for i while:

for letter in "Python":
    if letter == "h":
	print("        Jsme přerušeni!")
        continue
    print("Current Letter: ", letter)	
Current Letter:  P
Current Letter:  y
Current Letter:  t
        Jsme přerušeni!
Current Letter:  o
Current Letter:  n

nebo:

var = 6
while var > 0:
    var = var - 1	
    if var == 3:
	print("        Jsme přerušeni!")
        continue
    print("Current var. value: ", var)
print("Adieu!")
Current var. value:  5
Current var. value:  4
        Jsme přerušeni!
Current var. value:  2
Current var. value:  1
Current var. value:  0
Adieu!

6.10 Operátor 'in' a 'not in'

Operátor in, not in přezkoumá, zda je zadaný řetězec součástí jiného:

>>> 'p' in 'apple'
True
>>> 'i' in 'apple'
False
>>> 'ap' not in 'apple'
False
>>> 'pa' not in 'apple'
True
Všimněme si, že řetězec může být součástí sebe sama:
>>> 'a' in 'a'
True
>>> 'apple' in 'apple'
True

Použitím operátoru in a zřetězení můžeme napsat funkci, která odstraní všechny samohlásky z řetězce:

def remove_vowels(str):
    samohl = "aeiouyAEIOUY"
    str_bez_samohl = ""             # akumulátor
    for letter in str:
        if letter not in samohl:
            str_bez_samohl += letter
    return str_bez_samohl           

Prázdný objekt, označený jako akumulátor, je kontejner (zde řetězec) s rozšiřujícím se obsahem.
Podobným objektem je počítadlo, kde se mění jen počáteční stav čísla.


6.11 Porovnávání řetězců

Při porovnávání řetězců se porovnávají kódová čísla znaků se stejným indexem. Postupuje se zleva doprava.

Rovnost řetězců zjistíme:

word = "Zebra"
if word == "banana":
   print ("Ano, banány máme!")
print("Žádný takový!")

Jiné relační operátory jsou užitečné při uspořádávání slov podle abecedy:

if word < "banana":
   print("Your word, " + word + ", comes before banana.")
elif word > "banana":
   print("Your word, " + word + ", comes after banana.")
else:
   print("Maybe, we have bananas!")

Musíme si však být vědomi toho, že Python řadí velká písmena (v důsledku svých číselných hodnot) před malá, proto:

Your word, Zebra, comes before banana.

Souvislost znaku s číselnou hodnotou nám také umožňuje použít funkce min(), max(), ord() a chr():

>>> min("žoužel"), max("žoužel")
('e', 'ž')
>>> ord(min("žoužel")), ord(max("žoužel"))
(101, 382)
>>> chr(101), chr(382)
('e', 'ž')

6.12 Použití metod

Řetězce jsou sice neměnitelné ale lze libovolně upravovat jejich (často interně vytvářené) kopie. Pro tento účel existuje řada funkcí a metod.

Metoda '.removeprefix/suffix()'

Těmito metodami lze změnit začátek a konec řetězce:

>>> "some Text".removeprefix("some ")
'Text'
>>> "some Text".removesuffix("Text")
'some '

Metoda '.replace()'

Tato metoda string.replace(old, new [,count]) vytvoří kopii zadaného řetězce, v němž nahradí stávající substring novým substringem a to pro zadaný počet substringů (implicitně pro všechny).

>>> ring = "horo, horo, vysoká jsi"
>>> (fing := ring.replace("horo", "Horo", 1))
'Horo, horo, vysoká jsi'

Použitím metody replace lze částečně kompenzovat neexistenci procedury "remove" pro řetězce:

>>> abr = "abrakadabra"
>>> abr.replace("a", "")
'brkdbr'

V případě potřeby si můžeme napsat proceduru (zde funkci) sami, například chceme-li zbavit řetězec předdefinované sady znaků, prezentované jako "punctuation".
K vlastnímu vyzkoušení použijte prostředí IDLE:

import string

def remove_punct(s): 
    s_without_punct = ""     proměnná zvaná akumulátor
    for letter in s:
        if letter not in string.punctuation:
            s_without_punct += letter
    return s_without_punct
	
str = "Až na severní pól, běží liška!"	

print(remove_punct(str))

# Ctrl-S, F5
Až na severní pól běží liška
Poznámka:
>>> import string as str
>>> str.punctuation
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
Cvičení: Můžeme si definovat vlastní soubor znaků, napříkad "žšěíó".
Pro jeho použití upravte funkci remove_punct(s).

Metoda 'find'

Vrací index prvního výskytu zadaného substringu v prohledávaném řetězci. Schéma volání metody find (parametry v hranatých závorkách jsou nepovinné) je toto:

string.find(sub [,start [, end]])

sub - hledaný substring
start - začátek hledání; implicitně je 0
end   - konec hledání; implicitně konec řetězce

Metoda find je ve skutečnosti všestrannější než naše uživatelská funkce. Umí nalézt i části řetězců, nejenom pouhé znaky:

>>> tanec = "Dokolečka dokola"
>>> tanec.find("leč")
4

Jako naše funkce i tato metoda přijímá nepovinný argument, který určuje index u kterého má začít:

>>> tanec.find("kol", 4)
12

Odlišně od naší funkce, druhý nepovinný parametr metody určuje index, kde má hledání skončit:

>>> tanec.find("la", 1, 15)
-1                        # návratová hodnota v případě neúspěchu

V tomto případě skončí hledání nezdarem, protože se substring la nevyskytuje v intervalu od 1 do 15 (nikoliv včetně).

Metoda 'count'

Vestavěnou metodu count použijeme při počítání výskytu zadaného znaku či skupiny znaků v řetězci:

string.count(value [, start [, end]])
>>> "abrakadabra".count("a")
5
>>> "abrakadabra".count("ra")
2
>>> "Až na severní pól".count(" ")
3

6.13 Sestavení funkce 'find'

Uživatelská funkce find přijme znak a nalezne index místa, kde se znak nachází. Není-li znak nalezen, funkce vrací -1.

def find(strng, ch):
    index = 0
    while index < len(strng):
        if strng[index] == ch:
            return index
        index += 1
    return -1

V této funkci se opět setkáváme s příkazem return uvnitř smyčky. Je-li str[index] == ch, je funkce ukončena předčasným přerušením smyčky.

Není-li znak v řetězci obsažen, potom program opustí smyčku normálně a vrátí -1.

Tento způsob výpočtu je někdy nazýván traverzování Heuréka, protože jakmile nalezneme co hledáme, můžeme zvolat „Heuréka” a skončit hledání.

Pro stanovení počátku pro hledání můžeme do funkce přidat třetí parametr:

def find1(strng, ch, start):
    index = start
    while index < len(strng):
        if strng[index] == ch:
            return index
        index += 1
    return -1
Volání find1("banana","a",2) nyní vrátí pozici prvního a za indexem 2.

Funkci si vylepšíme úpravou parametru start. Připojením hodnoty z něj učiníme paramter s počáteční hodnotu, který je volitelný v tom smyslu, že jej můžeme při volání případně vynechat:

def find2(strng, ch, start=0):
    index = start
    while index < len(strng):
        if strng[index] == ch:
            return index
        index += 1
    return -1
Výsledek volání find2("banana", "a", 2) bude stejný jako find1("banana", "a", 2), zatímco při volání find2("banana", "a") bude parametr start nastaven na počáteční hodnotu 0.

Přidáním dalšího volitelného parametru do fce find zajistíme prohledávání jak dopředu, tak dozadu:

def find3(strng, ch, start=0, step=1):
    index = start
    while 0 <= index < len(strng):
        if strng[index] == ch:
            return index
        index += step
    return -1
Zadání hodnoty -1 pro step způsobí zmenšování stavu počítadla. Pro tuto změnu bylo nutné ošetřit jak horní tak i dolní mez proměnné index.


6.14 Formátování řetězců I

Starší a v Pythonu 3.x stále použitelný způsob formátování řetězce je s použitím interpolačního operátoru % spolu s konverzními specifikacemi.

Konverzními specifikacemi jsou znaky, které zastupují zamýšlený formát vkládané hodnoty, například:

Schema formátování řetězce vypadá takto:

<FORMAT >  %  < ( VALUES ) >
Část FORMAT obsahuje kombinaci řetězců a konverzních specifikací. Následuje samotný interpolační operátor % a za ním výčet hodnot, doplňovaných za konverzní specifikace. Závorky jsou nepovinné, je-li hodnota pouze jedna.

Nejlépe si to ukážeme na několika příkladech:

>>> "Jmenuje se %s." % "Arthur"
'Jmenuje se Arthur.'
>>> name = "Alice"
>>> age = 10
>>> "I am %s and I am %d years old." % (name, age)
'I am Alice and I am 10 years old.'
>>> n1 = 4
>>> n2 = 5
>>> "2**10 = %d and %d*%d = %f"  %  (2**10, n1, n2, n1*n2)
'2**10 = 1024 and 4*5 = 20.000000'
>>> 

V prvním uvedeném příkladě je jediná konverzní specifikace %s, která označuje řetězec. K ní se přiřazuje jediná hodnota "Arthur" a není uzavřena v závorkách.

Ve druhém příkladě má name hodnotu řetězce "Alice" a age má hodnotu celého čísla 10. Tyto se přiřazují ke dvěma konverzním specifikacím %s a %d; druhá specifikace je označením celého dekadického čísla.

Ve třetím příkladě mají proměnné n1 a n2 celočíselné hodnoty 4 a 5. Ve formátovaném řetězci jsou čtyři konverzní specifikace: tři %d a jedna %f. Písmeno f naznačuje, že příslušná hodnota má být ve tvaru čísla s plovoucí desetinnou čárkou. Čtyři hodnoty, které se vztahují k uvedeným čtyřem konverzním specifikacím jsou: 2**10,n1,n2 a n1*n2.

V následující ukázce vidíme povel k tisku bez formátování řetězce:

i = 1
print("i\ti**2\ti**3\ti**5\ti**10\ti**20")
while i <= 10:
   print(i,'\t',i**2,'\t',i**3,'\t',i**5,'\t',i**10,'\t',i**20)
   i += 1    

Tento program vytiskne tabulku různých mocnin čísel od 1 do 10. V uvedeném tvaru je rovnání výsledků do sloupců způsobené znakem tabelátoru (\t) které selhává jakmile hodnoty výsledků zaberou 8 míst:

i       i**2    i**3    i**5    i**10   i**20
1       1       1       1       1       1
2       4       8       32      1024    1048576
3       9       27      243     59049   3486784401
4       16      64      1024    1048576         1099511627776
5       25      125     3125    9765625         95367431640625
6       36      216     7776    60466176        3656158440062976
7       49      343     16807   282475249       79792266297612001
8       64      512     32768   1073741824      1152921504606846976
9       81      729     59049   3486784401      12157665459056928801
10      100     1000    100000  10000000000     100000000000000000000

Mohli bychom změnit šířku sloupce ale vidíme, že první sloupce již teď mají více místa než potřebují. Nejlepší bude určit šířku pro každý sloupec jednotlivě. Jak lze tušit, řešení poskytuje formátovaný řetězec :

i = 1 
print("%-4s%-5s%-6s%-8s%-13s%-15s" %
   ('i', 'i**2', 'i**3', 'i**5', 'i**10', 'i**20'))
while i <= 10:
   print("%-4d%-5d%-6d%-8d%-13d%-15d" % (i, i**2, i**3, i**5, i**10, i**20))
   i += 1    

Běh této verze dává následující výstup:

i   i**2 i**3  i**5    i**10        i**20          
1   1    1     1       1            1              
2   4    8     32      1024         1048576        
3   9    27    243     59049        3486784401     
4   16   64    1024    1048576      1099511627776  
5   25   125   3125    9765625      95367431640625 
6   36   216   7776    60466176     3656158440062976
7   49   343   16807   282475249    79792266297612001
8   64   512   32768   1073741824   1152921504606846976
9   81   729   59049   3486784401   12157665459056928801
10  100  1000  100000  10000000000  100000000000000000000

Pomlčka - za každou konverzní specifikací určuje zarovnání zleva. Číselné hodnoty určují minimální délku, takže %-13d je minimálně třináctimístné číslo zarovnané zleva.


6.15 Formátování řetězců II

Novější způsob formátování výstupu je pomocí metody .format() v sestavě "formátovaný_řetězec_s_výměnnými_poli" . format().

Výměnná pole jsou instrukce, uzavřené ve složených závorkách { }. Vše, co je mimo těchto závorek, je považováno za text, který je v nezměněném stavu kopírován do výstupu.

Pro popis skladby výměnného pole se domluvme, že hranatými závorkami označíme údaj, který může chybět.

Skladbu výměnného pole tedy vyjádříme schematicky takto:

{ [field_name] [!conversion] [:format_spec] }

Nejjednodušší možná forma výměnného pole jsou prázdné složené závorky { }.

Sektor  field_name
je buď číslo, nebo klíčové slovo. Číslo odkazuje na poziční argument, klíčové slovo na pojmenovaný argument metody .format(). Tvoří-li čísla řadu 0, 1, 2, ..., lze je vynechat.

Více než slova řekne ukázka:

>>> "Od {} do {}" .format("rána", 22.00)
'Od rána do 22.0'  # totéž jako "Od {0} do {1}"
>>> "Jmenuji se {name}" .format(name = "Pavel")
'Jmenuji se Pavel'

Sektor  !conversion
způsobí změnu typu před formátováním. Používá se značení
!s, které volá funkci str(), jež vrací objekt coby řetězec
!r, které volá funkci repr(), jež vrací řetězec obsahující tisknutelnou prezentaci objektu
!a, které volá funkci ascii(), jež vrací řetězec, jehož non-ASCII znaky jsou nahrazeny escape sekvencí.

Ukázka přiblíží způsob použití:

>>> "Harold je chytrý {0!s}" .format("chlapeček")
'Harold je chytrý chlapeček'
>>> "Harold je chytrý {0!r}" .format("chlapeček")
"Harold je chytrý 'chlapeček'"   
>>> "Harold je chytrý {0!a}" .format("chlapeček")
"Harold je chytrý 'chlape\\u010dek'"        # ošetřené ne-ASCII

Sektor  :format_spec
upřesňuje, jak má být hodnota prezentována, to jest určuje:
šířku - pole pro zadávanou hodnotu
výplň - libovolný znak kromě závorek { }; následuje pokyn pro zarovnání
zarovnání - vlevo (<), vpravo (>), na střed (^) a mezi(=) signum a číslici
signum - +, -, " ", (také # a 0)
přesnost - počet desetinných míst čísla: . údaj
typ - určuje způsob prezentace dat, například b je pro binární formát, d je pro decimální celé číslo, f pro formát float

Ukázka přiblíží způsob použití:

>>> "{:<25}" .format("zarovnáno vlevo")
'zarovnáno vlevo          '
>>> "{:>25}" .format("zarovnáno vpravo")
'         zarovnáno vpravo'   
>>> "{:ˇ^25}" .format("hulín")
'ˇˇˇˇˇˇˇˇˇˇhulínˇˇˇˇˇˇˇˇˇˇ'

Další zajímavé příklady namátkou:

>>> import math
>>> print("Hodnota Pí je asi {0:.3f}" .format(math.pi))
Hodnota Pí je asi 3.142
>>>  
>>> telef = {"Jan":4127, "Dana":4098, "Ota":863678}
>>> for name, phone in telef.items():
        print("{0:10} ==> {1:10d}" .format(name, phone))
...
Ota        ==>    863678
Dana       ==>      4098
Jan        ==>      4127

Další příklady lze nalézt v literatuře (pohříchu anglické), například The Python Tutorial - Input and Output

Najde se tam také tento užitečný:

>>> for x in range(7,11):
...     print("{0:2d} {1:3d} {2:4d}" .format(x, x*x, x*x*x))
...
 7  49  343
 8  64  512
 9  81  729
10 100 1000
>>>


6.16 Formátování řetězců III

Nejnovější způsob formátování řetězců byl zaveden ve verzi Python 3.6. Označuje se jako formátovaný literál řetězce (formatted string literal), stručně f-string. Literál f-stringu se uvozuje písmenem f nebo F a lze použít obdobné konverze (!s, !r, !a) jako u předchozího způsobu.

Obdobně jako u předchozího způsobu může tento literál obsahovat výměnná pole, ohraničená složenými závorkami { }. Zatímco u předchozího způsobu odkazoval obsah těchto závorek pouze na konstantní hodnotu, u f-stringu může odkazovat také na výraz, funkci, metodu aj.

V následující ukázce vidíme volání funkce a metody:

>>> name = "IDLE"
>>> def to_lowercase(input):
...     return input.lower()

>>> f"{to_lowercase(name)} je zábavné."         volání funkce
'idle je zábavné.'

>>> f"{name.lower()} je zábavné."               volání metody
'idle je zábavné.' 

V další ukázce je odkaz na slovník:

>>> postava = {'name': 'Petr Parléř', 'age': 67}
>>> f"Stavitel {postava['name']} se dožil " \
... f"{postava['age']} let." 
'Stavitel Petr Parléř se dožil 67 let.'
# konverzní flag !a pro ASCII - viz 6.16:
>>> f"Stavitel{postava['name']!a}"   
"Stavitel'Petr Parl\\xe9\\u0159'"

Ukázka interakce f-stringu s instancí třídy - viz Kapitola 12.9 a cvičení 12.15/6.

Python 3.8 přináší rozšíření f-stringu o rovnítko za jménem, které způsobí vytištění předem přiřazené hodnoty:

>>> python = 3.8

>>> f"{python=}"
'python=3.8'
>>> f"{python = :> 5}"            # případně s formátováním výstupu:
'python =   3.8'

Další možností je použití mrožího operátoru uvnitř f-stringu:

>>> import math
>>> r = 2.4
>>> f"Tyč o průměru {(d := 2 * r)} cm má obvod {math.pi * d:.2f} cm"
'Tyč o průměru 4.8 cm má obvod 15.08 cm'

6.17 Dokumentační řetězce

Kromě jednoduchých a dvojitých uvozovek zná Python také řetězce s trojitými uvozovkami, tvořenými jednoduchými i dvojitými znaky. Řetězce mohou procházet přes více řádků.

>>> """Toto je jedna možnost."""

>>> '''Toto je druhá možnost.'''

Uvnitř řetězce s trojitými uvozovkami mohou být uvozovky jednoduché i dvojité:

>>> ''' "Ach ne", zvolala, "Benovo kolo je rozbité" '''
' "Ach ne", zvolala, "Benovo kolo je rozbité" '
>>> 

Trojité uvozovky se používají pro dokumentační řetězce (docstrings). Docstring je řetězec, umístěný jako první text v modulu, funkci, třídě nebo v definici metody:

def mocnina(m, n=3):
    '''
    Funkce počítá n-tou mocninu s pevně
    nastaveným exponentem n=3; lze jej změnit
    '''
    print(m**n)

Informaci o funkci získáme evokací (voláním, neboli také "aplikací") vestavěné metody .__doc__ pro objekt funkce:

>>> print(mocnina.__doc__)
Funkce počítá n-tou mocninu s pevně
nastaveným exponentem n=3; lze jej změnit
>>> 

Dokumentačního řetězce použijeme k získání stručné informace o jakémkoli vestavěném objektu (funkci):

>>> print(len.__doc__)
Return the number of items in a container.
>>> 

6.18 Glosář

sekvence (sequence)
Uspořádaná množina prvků. Podmnožina této množiny se nazývá subsekvence.
index
Interní hodnota, použitá k označení prvku uspořádané řady, na příklad znaku v řetězci.
traverzovat (traverse)
Probírat postupně jednotlivé prvky dané řady a s každým provést obdobnou operaci.
úsek (slice)
Část řetězce, vymezená rozsahem indexů.
whitespace
Netištěné znaky pro ovládání kurzoru. Všechny tyto znaky obsahuje konstanta string.whitespace.
dokumentační řetězec (docstring)
Řetězcová konstanta, uvedená na prvním řádku funkce nebo modulu (a jak uvidíme později i třídy a metody). Dokumentační řetězce vhodně spojují programový kód s jeho komentářem. Používají se také pro automatické testování kódu s modulem doctest.

6.19 Cvičení

  1. V návaznosti na odstavec 6.7 upravte skript tak, aby se Ouack a Quack vytiskly správně:
    prefixes = "JKLMNOPQ"
    suffix = "ack"
    
    for letter in prefixes:
        print(letter + suffix)
    
  2. Zapouzdřete následující sekvenci příkazů do funkce count_letters_acc
    fruit = "banana"
    count = 0
    for char in fruit:
        if char == 'a':
            count = count + 1
    print(count)
    
    a zobecněte ji tak, aby přijímala řetězec a písmeno jako argument a vracela počet výskytů písmena v řetězci. Řešení vložte do skriptu whatLetters_str.py
  3. Tutéž úlohu (výskyt znaků) řešte vestavěnou metodou string.count(letters), která počítá výskyt nejenom písmen ale i zadaných substringů.
  4. V následujících úlohách použijeme k ověření správnosti vašeho řešení doctesty, se kterým jsme se seznámili v kapitole 5.10. Vytvořte soubor se jménem stringtools.py a na jeho spodní okraj vložte tento veršíček:

    if __name__ == '__main__':
        import doctest  
        doctest.testmod() 
    
    Přidávejte těla funkcí tak, aby prošla zkouškou doctestů. Ty budou u některých výsledků vyžadovat i apostrofy. Přičtete je k výstupu:
    print("'" + <výstup> + "'")
    nebo použijte funkci
    return <výstup>
    

    Návštěva stránky String Methods může být v případě potřeby prospěšná.

    1. def reverse (s):
         """
         >>> reverse('happy')
         'yppah'
         >>> reverse('Python') 
         'nohtyP'
         >>> reverse('')
         ''
         >>> reverse('P')
         'P'
         """
      

      Jednoduché řešení úsekovým operátorem

    2. def mirror (s):
          """
          >>> mirror ('good')
          'gooddoog'
          >>> mirror ('yes') 
          'yessey'
          >>> mirror ('Python')
          'PythonnohtyP'
          >>> mirror ('')
          ''
          >>> mirror ('a')
          'aa'
          """
      

      Prosté spojení dvou řetězců.

    3. def is_palindrome (s):
          """
          >>> is_palindrome('abba')
          True
          >>> is_palindrome('abab') 
          False
          >>> is_palindrome('tenet')
          True
          >>> is_palindrome('banana')
          False
          >>> is_palindrome('straw warts')
          True
          """
      

      Použijete řešení ad a).

    4. def remove_letter (letter, strng):
          """
          >>> remove_letter ('a', 'apple')
          'pple'
          >>> remove_letter ('a', 'banana') 
          'bnn'
          >>> remove_letter ('z', 'banana')
          'banana'
          >>> remove_letter ('i', 'Mississippi')
          'Msssspp'
          """
      

      Lze řešit prostřednictvím idiomu for .. in .. nebo metodou replace.

    5. def count_sub (sub, s):
          """
          >>> count('is', 'Mississippi')
          2
          >>> count('an', 'banana') 
          2
          >>> count('ana', 'banana')
          1
          >>> count('nana', 'banana')
          1
          >>> count('nanan', 'banana')
          0
          """
      

      Napoví stránka "String Methods".

    6. def remove_sub (sub, s):
          """
          >>> remove('an', 'banana') 
          'bana'
          >>> remove('cyc', 'bicycle')
          'bile'
          >>> remove('iss', 'Mississippi')
          'Missippi'
          >>> remove('egg', 'bicycle')
          'bicycle'
          """
      

      Napoví stránka "String Methods".

    7. def remove_all (sub, s):
          """
          >>> remove_all('an', 'banana') 
          'ba'
          >>> remove_all('cyc', 'bicycle')
          'bile'
          >>> remove_all('iss', 'Mississippi')
          'Mippi'
          >>> remove_all('egg', 'bicycle')
          'bicycle'
          """
      
  5. Vyzkoušejte následující formátující řetězcové operace v konzole Pythonu a zaznamenejte výsledky:
    >>> "%s %d %f" % (5,5,5)
    
    >>> "%-.2f" % 3
    
    >>> "%-10.2f %-10.2f" % (7, 1.0/2)
    
    >>> print(" $%6.2f\n $%6.2f\n $%6.2f" % (3, 4.5, 11.2))
        
    
    Totéž proveďte pomocí funkce .format().
previous up next hi end end