![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Iterace
je opakovaný výpočet pro hodnoty jednotlivých členů
Iterábl vlastní magickou (
Iterace iteráblu produkuje 'dychtivý' (
Iterátor
je objekt, vlastnící vestavěnou funkci
Implicitně si iterátor pro zadaný iterábl vytváří smyčka
Iterátory jsou výhodné tím, že snižují spotřebu paměti; vyprázdněný iterátor je "garbage collected".
Iterátor lze generovat i generátorovou funkcí a generátorovým výrazem
- viz odst. 3.6.
Iterátory, definované třídou, jsou popsány v Kap. 10
.7.
Funkce
>>>li = [2, 5, 0]# iterábl >>>ili =iter (li)# vytvoření iterátoru >>> ili = li.__iter__ ()# alternativní způsob >>>(ili) next # první krok iterace 2 >>> ili.__next__ ()5 >>> next (ili)# poslední krok iterace 0 >>>next (ili)StopIteration # info o konci iterace
Iterátor je v této chvíli prázdný. Opětovně použitelný iterátor
vytvoříme opětovným použitím funkce
To platí i při aplikaci smyčky
>>>ili =iter (li) >>>next (ili) 2 >>>for i in ili: next (ili)StopIteration Nutno poznamenat, že při aplikaci smyčky for .. pro iterábl li žádné StopIteration nehrozí, neboť si smyčka vytvoří svůj vlastní interní iterátor: >>>for i in li:
Jednotlivé elementy sekvencí jsou interně
Rozdah indexů vychází ze zadané sekvence, jak ilustruje následující obrázek:
Indexování zleva začíná nulou, indexování zprava doleva se provádní pomocí záporných čísel. Výběr začíná prvním indexem a končí posledním:
>>>pozdrav = "Hello World" >>> pozdrav[5] ' '# zde mezera mezi slovy >>> pozdrav[-5] 'W' >>> pozdrav[11]IndexError: string index out of range >>> pozdrav.__getitem__ (0) 'H'
Hodnoty elementů objektu typu
>>>dc = {"m": 5, "n": 6}# objekt s klíči "m", "n" >>> dc["m"]# použití závorkového operátoru 5 >>> dc.__getitem__ ("n")# použití metody 6 >>>for i in dc: # použití indexu ve smyčce
Vymezená část sekvence typu
Skladba příkazu pro
Není-li
V následující tabulce jsou jsou uvedeny různé variace úseků zadané sekvence
0 1 2 3 4 5 6 # indexy 0 ÷ 6 >>>seq = [1, 2, 3, 4, 5, 6, 7]# upravovaná sekvence -7 -6 -5 -4 -3 -2 -1 # indexy -1 ÷ -7 >>>a = seq[::]; a# dtto seq[:] nebo seq[0:(len(seq)+1):1] [1, 2, 3, 4, 5, 6,7] >>>b = seq[2::]; b# dtto seq[2:] nebo seq[2:(len(seq)+1):1] [3, 4, 5, 6, 7] >>>c = seq[:5:]; c# dtto seq[:5] nebo seq[0:5:1] [1, 2, 3, 4, 5] >>>d = seq[2:6:]; d# dtto seq[2:6] nebo seq[2:6:1] [3, 4, 5, 6] >>>e = seq[::2]; e# nebo seq[0 : (len(seq)+1) : 2] [1, 3, 5, 7] >>>f = seq[::-2]; f [7, 5, 3, 1] >>>g = seq[2:6:2]; g [3, 5] >>>h = seq[2:6:-2]; h []# prázdná subsekvence >>>i = seq[6:2:2]; i []# prázdná subsekvence >>>j = seq[3:-5]; j []# prázdná subsekvence >>>k = seq[-5:3]; k []# prázdná subsekvence >>>l = seq[2::2]; l# nebo seq[2:(len(seq)+1):2] [3, 5, 7] >>>m = seq[8:1:-2]; m [7, 5, 3] >>>n = seq[-4:-2]; n# nebo seq[-4:-2:1] [4, 5]
Pokud mají úsek a krok opačnou orientaci,
je výsledkem prázdný úsek - viz případ
Dva příkazy na jednom řádku (oddělené středníkem) lze zadat pouze v REPL.
Funkce
Podle znaménka
indexů start, end může být úsek orientován zleva doprava nebo
zprava doleva. Stejně tak krok může směřovat vpravo či vlevo - opět v
závislosti na kladné či záporné hodnotě kroku.
Působení vestavěné funkce
>>>seq = "Nazdar Pythone!" >>>slice_obj =slice (3,11); slice_obj slice(3, 11, None)# objekt funkce slice() # Tento objekt lze uplatnit na sekvence různých typů: >>>sub_seq = seq[slice_obj]; sub_seq 'dar Pyth'# Případně lze pro jedno použití slice(3,11) dosadit přímo : >>>sub_seq = seq[slice(3,11)]; sub_seq 'dar Pyth'
Dobrou zvláštní okolností při zadávání kladně i záporně
orientovného úseku je skutečnost, že jeho deklarovaná délka může být
delší než
>>>seq_op = [1, 2, 3, 4, 5, 6, 7] >>>seq_sl = "Nazdar Pythone!" >>>d = seq_op[2:9]; d [3, 4, 5, 6, 7] >>>f = seq_sl[slice(-10, -20, -1)]; f radzaN
# V jednom řádku: >>>x ,y ,z = 10,20,30; x,y,z# 3 jména --> 3 hodnoty (10, 20, 30) >>> a*b*c 6# Ve dvou řádcích: >>>seq = 1,2,3# 1 jméno <-- 3 hodnoty >>>a ,b ,c = seq# 3 jména <-- 1 entice # Při přiřazení došlo k rozbalení hodnot z entice.
Při stejném počtu prvků na obou stranách proběhne jejich propojení v zadaném pořadí.
Výčet hodnot na pravé straně může mít formát
>>>a ,b = 12, 22; a,b# tuple = tuple (12, 22) >>>a ,b = [12, 22]; a,b# tuple = list (12, 22) >>>c ,d ,e = "Haf"; c,d,e# tuple = string ('H', 'a', 'f') >>>f ,g = {5, "pivo", 5}; f,g# tuple = set ('pivo', 5) >>>f ,g = {"j":15, "k":25}; f,g# tuple = dict ('j', 'k')(vrací jen klíče) >>>b ,f ,l = range(3); b,f,l# tuple = range (0, 1, 2)
Hromadným přiřazením rozbalíme slovník pomocí vestavěné methody
>>>dic = {'a':2, 'b':4, 'c':10}# deklarace slovníku >>>for pol in dic .items() :# vestavěná methoda key, value = pol# hromadné přiřazení
Hromadné přiřazení lze výhodně použít i ve spojení s funkcí, pokud její invokace produkuje stejný počet hodnot jako zadaný počet proměnných :
>>>def mocniny (num):return num, num**2, num**3# fce vrací 3 hodnoty # hromadné přiřazení k výstupu volané funkce >>>num ,sqr ,cub = mocniny(2) >>> num, sqr, cub# invokace funkce (2, 4, 8)
Hromadné přiřazení použijeme i ve spojení s komprehencí iteráblu (viz 3.5):
>>>x ,y ,z = (x**2for xin (1,3,5))# hromadné přiřazení >>> x,y,z# invokace (1, 9, 25)
Hromadným přiřazením lze rozbalit i vnořené iterábly:
>>>body = (1,2), (-1,-2)# entice entic # hromadné přiřazení k hodnotám objektu "body": >>> (x1,y1), (x2,y2) = body >>>
Hromadné přířazení použijeme výhodně při záměně přiřazení:
>>>x ,y ,z = 10,20,30 >>>z ,y ,x = x,y,z >>> x,y,z (30, 20, 10)
Alternativní označení hromadného přiřazení je
Pokud je na levé straně
>>> *a , = 1,2,3,4,5; a# *a, je entice (tuple) [1,2,3,4,5]# tuple 'rozbaluje' do listu >>> [*a ] = 1,2,3,4,5; a# [*a] je seznam (list) [1,2,3,4,5]# list 'rozbaluje' do listu
Ve výčtu jmen na levé straně smí být jen jedna hvězdičková
proměnná. Neohvězdičkovaná jména se nazývají
>>>a ,*b ,c = 1,2,3,4,5; a,b,c (1,[2,3,4],5) >>>a ,*_ ,c = 1,2,3,4,5; a,_,c# _ je 'anonymní' proměnná (1,[2,3,4],5) >>>a ,*b ,c = 7,8; a,b,c# OK: 3 <= 1 + 2 (7,[],8)# hodnoty 1,2 měly přednost, na b* nic nezbylo
Možné jsou i tyto (poněkud rozpustilé) kombinace:
>>>f ,*m ,(*ir ,il ) = 0,1,2,3,(4,5,6)# přiřazení >>> f; m; ir; il# invokace 0 [1, 2, 3] [4, 5] 6
Hvězdičkové operátory jsou mnohdy nezbytné pro rozbalení některých iteráblů:
>>> *ran, =range (8); ran# tuple či list na levé straně! [0, 1, 2, 3, 4, 5, 6, 7] >>>r =list (ran); r# alternativní invokace [0, 1, 2, 3, 4, 5, 6, 7] >>> *gen , = [2**xfor xin range (8)]; gen# komprehence [1, 2, 4, 8, 16, 32, 64, 128]
Hromadné přiřazení s hvězdičkovým členem usnadňuje přístup k prvkům iteráblu bez použití indexů:
>>>items = "zdař", 25, True, 2+5# Výběr pomocí indexů: >>>Výběr hromadným přiřazením: >>>first , *middle ,last = items >>>
Dekorace
>>>dic = {'a':2, 'b':4, 'c':10} >>>def fun (a,b,c):return a,b,c >>> fun(**dic) (2, 4, 10)
Jiný příklad se sloučením slovníků:
>>>prvý ,druhý = {"A": 1, "B": 2}, {"C": 3, "D": 4}# deklarace >>>spolu = {**prvý,**druhý,{'e': 5, 'f': 6)# deklarace >>> spolu# invokace ({'A': 1, 'B': 2, 'C': 3, 'D': 4, 'e': 5, 'f': 6})
Jen tak mimochodem - stejně úsporně lze totéž provést operátorem
>>>prvý ,druhý = {"A": 1, "B": 2}, {"C": 3, "D": 4} >>>spolu = prvý | druhý | {"e": 5, "f": 6} >>> spolu {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'e': 5, 'f': 6}
Komprehence je skladebný předpis pro vytvoření
Komprehenci ad b) lze ilustrovat matematickým výrazem, který pro
všechna
S = { 2*x | x € N, x² > 3 }
Obdobou výše uvedeného matematického výrazu může být toto schéma skladby v Pythonu:
S =< f(x) for x in <objekt> # bez podmínky S =< f(x) for x in <objekt> if <podmínka>
Závorky kolem deklarované komprehence jsou povinné a mají vliv na
výsledný typ modifikovaného objektu. Používají se závorky:
Idiom
Ukažme si konkretní příklad komprehence bez podmínky u iteráblů
Nutno poznamenat, že pro řádné provedení transformací je nutné aby
objekty typu
# Výpis výchozích iteráblů: li, tu = [1, 2, 3, 4], (1, 2, 3, 4)# list, tuple rg, sg =range (2,6), "růže"# range, string st = {4, 7, 4, True}# set fs =frozenset (st)# frozenset dc = {4:"size", 5:"Karel"}# dictionary by =bytes (sg, 'utf-8')# bytes from string ba, mv =bytearray (by),memoryview (by)# bytearray, memoryview # Použité závorky ( <> =[], (), {} ) mají vliv na výsledný typ
modifikovaného objektu. Pokusíme-li se o obecný záznam zamýšlené komprehence, mohli bychom pro některý z "výchozích" iteráblů napsat třeba toto:mod_obj =< x*2 for x initerable > # kde <> =[], {} # Kulaté závorky () použijeme s funkcítuple ():mod_obj =tuple (x*2 for x initerable )# Bez funkce tuple získáme místo upraveného objektu generátorový
objekt, například:gen_obj = (x*2 for x initerable ); gen_obj<generator object <genexpr> at 0x00000124DACB2810>
Jak uvedeno, iterábly lze komprehovat pro výstup ve formátu
Dále si ukážeme komprehenci s podmínkou:
>>>numbers = [1, 3, 2, 5, 3, 1, 4] >>> {x**2 for x innumbers if x**2 > 3} {16, 9, 4, 25}# komprehence s podmínkou a redukcí >>> >>>terms = ('bin', 'Data', 'Desktop', '.bashrc', '.ssh', '.vimrc') >>> [name for name interms if name[0] != '.'] ['bin', 'Data', 'Desktop']# komprehence s podmínkou
Výrazových předpisů může být v jedné komprehenci více:
>>> [(x, x**2, x**3) for x innumbers ]# komprehence seznamu [(1, 1, 1), (3, 9, 27), (2, 4, 8), (5, 25, 125) ...]
Dostali jsme výpis entic pro každý (i opakovaný) prvek zadaného seznamu . Výpis bez opakování získáme komprehencí setu místo seznamu.
Může být více i poskytnutých objektů:
>>>numbers = (1, 2, 3, 4) >>>letters = ['a', 'b', 'c'] >>> [n*letter for n innumbers forletter in letters] ['a', 'b', 'c', 'aa', 'clr-mm', 'cc', 'aaa', 'clr-mmb', 'ccc', 'aaaa', 'clr-mmclr-mm', 'cccc']
Zajímavá je úprava argumentu v této komprehenci:
>>> [v*2 for v in ("a", 5, True)]# True*2 = 1*2 = 2 ['aa', 10, 2]
Za povšimnutí stojí i toto spojení komprehence s formátováním řetězce dle kap. 6.8.2:
>>>chlapci = ["Pavel", "Petr", "Jan"] >>>synci = ["{} Novotný".format (boy) for boy in chlapci] >>> synci ['Pavel Novotný', 'Petr Novotný', 'Jan Novotný']
Ukázka komprehence setu z řetězce s podmínkou:
>>>s = {v for v in "ABCDABCD" if v not in "CB"}; s {'A', 'D'}
Komprehencí setu z řetězce lze s pomocí funkce
>>>d = {key:val for key,val inenumerate ('ABCD') if val not in "CB"} >>> d {0: 'A', 3: 'D'}
Jiný slovník vytvoříme z objektu typu
>>> {x: x**2 for x inrange (1, 6)} {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Zajímavé je použití pojmenovaného výrazu (mroží operátor - 2.6.4) při komprehenci seznamu:
>>>def f (x):return x + 2 >>>y := f (x), x/y) for x inrange (3)]) [[2, 0.0], [3, 0.3333333333333333], [4, 0.5]]# případně se zaokrouhlením des. čísla - viz vestavěné funkce >>>:= f (x),round (x/y, 2)] for x inrange (3)]) [[2, 0.0], [3, 0.33], [4, 0.5]]# případně s podmínkou a přehledněji: >>>round (x/y, 2)) for x inrange (3) if (y:= f (x)) > 0]) [(0, 2, 0.0), (1, 3, 0.33), (2, 4, 0.5)]
Následující komprehencí vybereme ze zadané množiny bodů ty, které
leží uvnitř kružnice o poloměru
>>>import math >>>radius = 2 >>> [(x, y) for x inrange (-2,3) for y inrange (-2,3) ifmath.sqrt (x**2 + y**2) <radius ] [(-1,-1), (-1,0), (-1,1), (0,-1), (0,0), (0,1), (1,-1), (1,0), (1,1)]
Generátorový objekt (neboli
Tento objekt je iterátorem, který neobsahuje žádná data, pouze je
evokuje v okamžiku invokace.
Generátorový výraz má formát idiomu
Iterace
V následující ukázce jsou obě iterace realizovány smyčkou
>>>st = "abakus"# iterovatelný objekt - iterábl >>>stv = (i for i in st)# generátorový objekt - iterátor >>>type (stv) <class 'generator'> >>> for i instv :# líná (lazy) iterace iterátoru a b a k u s >>> for i inst :# dychtivá (eager) iterace iteráblu a b a k u s
Generátorový výraz lze vytvořit pro traverzování všech
iteráblů. Zde vytvoříme iterátor pro iterábl typu
>>>gv = (i*i for i in range (5))# iterátor >>>for i in gv :end = ", ")# líná (lazy) iterace 0, 1, 4, 9, 16
Generátorová funkce je normální funkce, která místo příkazu
# count_to.py def count_to (m):# vrací iterátor n = 0while n <= m:yield n# poskytuje elementy iterátoru n += 1
>>>%Run count_to.py >>>ct = count_to(5)# gener. objekt, iterátor # Invokace iterátoru: >>>next (ct)# 1. krok iterace (funkce) 0 >>> ct.__next__ ()# 2. krok iterace (metoda ) 1 >>>for i in ct: # pokračování iterace smyčkou for ... >>>next (ct)StopIteration # iterátor je prázdný >>> ct = count_to(5)# objekt nutno obnovit >>>list (ct)) [0, 1, 2, 3, 4, 5]# výtisk generátor. objektu >>>list (ct)) []# iterátor je prázdný
Generátorový objekt (iterátor) vytvoří i tato generátorová funkce:
# squares.py def squares (start, stop):for i in range (start, stop):yield i * i
Přiřazením invokace generátorové funkce ke jménu vytvoříme
iterovatelný
Iteraci provedeme buď opakovaným použitím fce
%Run squares.py >>>sqr = squares(1,7)# lazy iterátor >>>next (sqr),next (sqr)# opakovaná iterace (1, 4) >>>for i in sqr: # smyčkou for ... vyčerpáme zbytek najednou 9 16 25 36 >>>sqr = squares(1,7)# obnova iterátoru >>>list (sqr)# najednou fcí list() [1 4 9 16 25 36]
Výpočet řady Fibonacciho čísel můžeme provést pomocí následující generátorové funkce s nekonečnou smyčkou:
fibo.py def fibo ():# generátorová funkce a, b = 0, 1while True:# nekonečná smyčka yield a a, b = b, a+b
Generátorový objekt (iterátor) s nekonečnou smyčkou voláme buď po
krocích nebo pro konkretní mez, určenou funkcí
%Run fibo.py >>>f = fibo()# generátorový objekt, iterátor >>>f .__next__ ()# --> 0 jiná verze fce next() >>>next (f),next (f)# --> (1, 1) # Můžeme pokračovat do omrzení pomocí fce range(): >>>for i in range (4):next (f),end =", ")# --> 2, 3, 5, 8 >>>for i in range (5):next (f),end =", ")# --> 13, 21, 34, 55, 89
Funkce
Generátorový výraz a generátorová funkce vrací generátorový objekt, jímž je pomalu (lazy) vyhodnocovaný iterátor.
Při líném výpočtu (lazy evaluation) se odkládá výpočet výrazu až do chvíle jeho potřeby. Důsledkem je zmenšená potřeba zdrojů (paměti) při zvýšeném výkonu procedury.
Lze sestavit potenciálně nekonečné struktury, např. smyčky - viz fibonacci().
Líný výpočet se obtížně kombinuje s imperativními strukturami jako je ošetření výjímek nebo vstup/výstup; může vytvářet "space leaks" (viz).
Příkladem procedury, uplatňující líný výpočet, je použití
slovníku v kapitole 9.12 (Switch case), kde u funkce
Všechny aktivity spuštěného programu se odvíjejí od textu,
vyskytujícího se v různých lexikálních (textových) oblastech kódu, zvaných jmenný prostor (namespace),
Těmito oblastmi (jmennými prostory) jsou:
Poznámka: O funkcích a třídách víme, že jejich definice se skládají ze záhlaví a z těla. Jejich lokální oblast je tvořena jejch vnitřním prostorem (tělem).
Jmennými oblastmi jsou tedy tyto oblasti (anglicky):
Objekty jsou přístupné prostřednictvím jmen, které na ně odkazují. Vázání objektu ke jménu je realizováno:
mamoj = "František"
def fun (m)# záhlaví # tělo
Jméno je na předním místě v pořadí důležitosti entit. Rozdělení zdrojového kódu do výše uvedených oblastí (
V jedné oblasti se nemohou současně vyskytovat dvě stejná jména, odkazující na různé hodnoty:
mam = "Alena"# deklarace přiřazení mam = "Petr"# změna přiřazení, předchozí deklarace neplatí
Mohou se však bez kolize vyskytovat současně v různých oblastech - v
různých
Globální proměnná je tvořená v globální oblasti skriptu a je přímo
dostupná z globální i z lokální oblasti (funkce) - interpret hledá jméno
tam, kde je žádané, případně pokračuje v
# glob_lok.py # globální prostor skriptu def fun ():# globální fce s lok. prostorem s = "Toto je lokální 's'"# lokální proměnná 1 # fce built-in
>>>%Run glob_lok.py # globální prostor interpreta Pythonu: >>>s = "Toto je globální 's'"# globální proměnná >>> fun()# invokace glob. fce Toto je lokální 's'# prezentace lok. proměnné >>># prezentace glob. proměnné
Přítomnost jména ve jmenném prostoru je zapsána ve jmenném registru,
jenž má formu slovníku (
# global.py # globální prostor skriptu a = [1, 2, 3, 4, 5]# globální proměnná skriptu def foo ():b = 11# lokální proměnná funkce locals ())# lokální funkce (built-in) globals ())# lokální funkce (built-in)
Vestavěné funkce
>>>%Run global.py >>> foo()# invokace globální funkce Locals: {'b': 11} Alelujá Globals: {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': < _frozen_importlib_external.SourceFileLoader object at 0x0000016539A047C0>, '__spec__': None, '__annotations__': {}, '__builtins__':, '__file__': 'F:\\Howto-py\\ch-03\\a_folders\\3.7.3\\global.py', 'a': [1, 2, 3, 4, 5], 'foo': <function foo at 0x000001653A325BD0>}
Všimněme si, že se proměnná
Jmennými oblastmi jsou oblasti (anglicky):
Souhrn lexikálních oblastí, z nichž je jméno dostupné, se nazývá scope tohoto jména. Do tohoto souhrnu patří jmenný prostor, v němž je jméno deklarováno a všechny níže postavené jmenné prostory. Obecně lze řící, že z výše postavené oblasti nelze volat jméno v níže postavené oblasti.
Dostupnost jmen si ukážeme na příkladu funkce
Následující soubor
# glob_local.py # globální prostor glob = "živijó"# globální proměnná def fun_glob ():# globální funkce lok = "lokální"# lokální proměnná # built-in funkce def fun_lok ():# lokální funkce inn = "inner"# vnitřní proměnná # přechod na nový řádek () locals ())globals ())fun_lok ()# invokace lokální funkce fun_glob ()# invokace globální funkce
>>>%Run glob_local.py lok, glob = živijó lokální glob, lok, inn = živijó lokální inner Locals: {'inn': 'inner', 'lok': 'lokální'} -- kávička -- Globals: {'__name__': '__main__', '__doc__': None, '__package__': None, ' ... ... 'fun_glob': <function fun_glob at 0x000002097EBC5BD0>}
Na příkladu tedy vidíme, že:
Proměnná
Její hodnota se mění v závislosti na tom, zda je realizovaný skript spuštěn přímo, nebo byl importován jako modul.
Označení
Idiom
Případ si ilustrujme na podrobnější ukázce. Mějme dva soubory, prvnímu budeme říkat modul, protože jej chceme importovat do jiného souboru:
# cosi_name.py def cosi ():
Provedením modulu v Thonny zjistíme, že je ticho po pěšině -
deklarovaná funkce nebyla volána, idiom
%Run cosi_name.py >>> cosi() Hodnota proměnné __name__ jest: __main__
Napíšeme si další soubor ...
# other_name.py import cosi_name # import modulu
... a po jeho spuštění zjistíme, že nám na prvním místě figuruje výstup z importovaného souboru cosi_name.py:
>>>%Run other_name.py Nekapišto.# naše záhada Pro cosi_name je __name__ = cosi_name# jasná páka Pro other_name je __name__ = __main__# jasná páka
Importovaný soubor
Introspekce Pythonu je akt zkoumání obsahu a vlastností jednotlivých jeho objektů. Za tímto účelem disponuje Python řadou vestavěných funkcí , z nichž některé již známe.
>>>omen = "Alenka" >>>dir (omen) ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', ...
>>> isinstance(5, int) True
>>> getattr(omen, "__doc__") "str(object='') -> str\nstr(bytes_or_buffer[, ... ... sys.getdefaultencoding().\nerrors defaults to 'strict'."
Dalším introspekčním nástrojem je t.zv.
docstring (dokumentační řetězec), což je krátká informace ve
formátu řetězce (
stvoří tento výstup
Přidejte volání funkce
Do souboru
1 1 2 3 3 6 4 10 5 15
Do souboru
Soubor s doctesty končí tímto kĂłdem:
if __name__ == '__main__': import doctest doctest.testmod()
Funkce
def num_digits (n): """ >>> num_digits(12345) 5 >>> num_digits(0) 1 >>> num_digits(-12345) 5 """
def num_even_digits (n): """ >>> num_even_digits(123456) 3 >>> num_even_digits(2468) 4 >>> num_even_digits(1357) 0 >>> num_even_digits(2) 1 >>> num_even_digits(20) 2 """
Nutno zajistit, aby mezi číslicemi výstupu byly mezery a aby za poslední číslicí žádná mezera nebyla. Numerický argument funkce nutno před manipulací přetvořit nadef print_digits (n): """ >>> print_digits(13789) 9 8 7 3 1 >>> print_digits(39874613) 3 1 6 4 7 8 9 3 >>> print_digits(213141) 1 4 1 3 1 2 """
Svá řešení ověřte pomocí doctestů.def sum_of_squares_of_digits (n): """ >>> sum_of_squares(1) 1 >>> sum_of_squares(9) 81 >>> sum_of_squares(11) 2 >>> sum_of_squares(121) 6 >>> sum_of_squares(987) 194 """
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |