![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Funkce print() se všemi svými parametry má tento tvar:
Kdo si přečetl odstavec 4.2.3 Parametry a argumenty *args, ví že parametr
Takže se nám povinný tvar volání funkce smrskne na:
přičemž i tento parametr lze vynechat a v tom případě nám funkce vytiskne prázdný řádek.
>>> print("\n")# vytiskne 1 prázdný řádek Případně >>> print(3*"\n")# vytiskne 3 prázdné řádky
Funkce
>>># (string, výraz, string) Je mi 21 let.# fce print() odebrala apostrofy
Použitelnou alternativou k funkci
51_stdout.py import sys s = ['Python', 'je', 'bezvadný']for e in s: # tisk na témže řádku sys .stdout.write ('\n')for e in s: # každý element na jiném řádku sys .stdout.write (e + '\n')
>>>%Run 51_stdout.py Python je bezvadný Python je bezvadný
Změnou argumentu
Změnou argumentu
>>>
Vhodné je také vědět, že příkaz k tisku funkce
>>># Po výstupu "Nazdar" přišel na řadu příkaz print()
Ve funkci s větvenými podmínkami s výhodou použijeme příkaz
def filtr (x):if x <= 0: return "Přirozené číslo, prosím"return x
Protože jsou tyto příkazy v alternativních podmínkách, provedou se pouze jednou - jakmile se jeden z příkazů
Kód, který je zapsán za příkazem
Je dobré aby každá možná cesta funkcí narazila na příkaz
def absolute_value (x):if x < 0: return -xelif x > 0: return x
Tato verze není zcela správná, protože bude-li
>>>
Příkaz
Příkaz print má formát funkce a slouží k zobrazení zadaného obsahu uvnitř funkce i mimo funkci.
>>># použití mimo funkci >>>def podíl (x, y):# použití uvnitř funkce # invokace funkce 2.6666666666666665
Příkaz return ukončí provádění funkce a vrátí vyhodnocený výraz (expression), je-li k dispozici. Není-li co vracet, vrací se implicitní hodnota "None".
Tato hodnota se však v shellu Pythonu či aplikace Thonny nezobrazuje. Chceme-li hodnotu None v shellu přesto zobrazit, použijeme příkaz
>>> def add_one(x):# funkce bez výstupu result = x + 1 >>> add_one(8)# výstup "None" se nekoná >>> print(add_one(8)) None# zde ano
Smyčka
for i in container: do something
st = {3.6, "cat", True}# kolekce typu set for i >in st:
>>> True 3.6 cat
Na výstupu idiomu
Iterace
sl = {1: "uno", 2: "duo", 3: "tre"}# kolekce typu dict for i in sl:
>>> 1 2 3
Případně:
sl = {1: "uno", 2: "duo", 3: "tre"}# kolekce typu dict for i,j in sl.items ():# dict.items() je vestavěná methoda
>>> 1 uno 2 duo 3 tre
O tom, že naše kontejnery jsou vybaveny metodou
dir (zkoumaný_objekt)
jejímž výstupem je seznam metod a funkcí zadaného objektu, v němž metodu
Stejně jako smyčka
Funkce
>>>f =open ("F:/Howtopy/files/week.txt")# iterátor pro week.txt >>>next (f)# první řádek souboru 'pondělí\n' >>>next (f)# další řádek souboru 'úterý\n' >>>for i in f: # zbývající řádky souboru středa čtvrtek ... >>> f.close ()# zavře soubor - viz kap.7.3
Následující příklad ukazuje použití zřetězení (concatenation) a smyčku
prefixes = "JKLMNOPQ"suffix = "ack"for letter in prefixes:
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.13.1.
Opakovaný výpočet pro jednotlivé elementy iteráblu lze s výhodou provést pomocí smyčky while:
Použití podmínky
def countdown (n):# parametr n jako počáteční stav počítadla while n > 0: # omezující podmínka # změna stavu počítadla
Příkaz
Formálněji popíšeme tok výpočtu s příkazem
Tělo podmínky tvoří všechny příkazy pod záhlavím podmínky se stejným odsazením.
Tento typ toku programu se nazývá smyčka, protože se opakovaně vracíme k počátku. Uvědomme si, že když je podmínka nepravdivá již při prvním běhu smyčkou, příkazy uvnitř smyčky se nikdy neprovedou.
Tělo smyčky by mělo měnit hodnotu jedné či více proměnných tak, aby se podmínka nakonec stala nepravdivou a smyčka skončila. Jinak by se opakovala do nekonečna, a byla by to nekonečná smyčka.
V případě funkce
def sequence (n):while n != 1: if n%2 == 0: # n je sudé n = n//2else : n = n*3+1
>>> sequence(4) 4, 2, >>> sequence(3) 3, 10, 5,16 , 8, 4, 2,
Podmínkou pro tuto smyčku je
Při každém průchodu smyčkou program vrácí hodnotu
Protože se
Odhlédneme-li od zmíněných čísel, je na místě otázka, zda umíme dokázat, že tento program je
konečný pro všechny možné hodnoty
Jiným příkladem použití smyčky while je traverzování po elementech seznamu:
trampol.py # Výběr slov se sudým pořadím slova = ["Copak", "je", "to", "za", "fešáka", "?"]i = 0délka =len (slova)while i < délka : if i % 2 == 1 :
>>>%Run trampol.py je, za, ?,
Následující ukázka demonstruje použití
while (user_input := input('Enter q or p: ')) != 'q':if user_input == 'p': else: # jeden blok kódu
>>>Enter q or p: p Hello! >>>Enter q or p: q Quit! >>>
K napsání užitečného programu potřebujeme mít možnost měnit chování programu v závislosti na splnění či nesplnění jistých podmínek.
Tyto podmínky se formulují pomocí
Tuto jednoduchou podmínku je vhodné použít jako součást jiné procedury, například funkce:
def odmocnina (x):if x >= 0:
Stejně jako funkce a jiné složené příkazy se podmínka
Poté, co se podmínka vyhodnotí jako pravdivá, provede se odsazená část složeného příkazu.
>>> odmocnina(5) odmocnina 5 = 2.23606797749979
Varianta s úpravou desetinného čísla pomocí
def odmocnina (x):if x >= 0: y = x**0.5
>>> odmocnina(5) odmocnina 5 = 2.24
Touto podmínkou realizujeme takzvané alternativní provedení, při němž existují dvě možnosti a podmínka určí, která z nich se provede:
x =int (input ("Zadej celé číslo: "))# ošetření vstupu z konzoly if x % 2 == 0: # při splnění podmínky # se provede odsazený příkaz else: # při nesplnění podmínky # se provede tento příkaz
>>>Zadej celé číslo: 15 15 je liché
Je-li zbytek po dělení dvěma roven nule, potom víme, že
Alternativám říkáme větve protože jsou rozvětvením toku programu.
Mimochodem, kdybychom potřebovali často posuzovat "lichost" či "sudost" čísel, mohli bychom si tento prográmek "zabalit" do funkce:def parita (x):if x%2 == 0: # % je operátor modulo else:
Podmínku
def parita (x):if x%2 == 0else print(x, " je liché")
Pro každou hodnotu
>>> parita(41) 41 je liché >>> y = 41; parita(y + 1) 42 je sudé
Někdy jsou více než dvě možnosti a my potřebujeme více než dvě větve. Použijeme seriově uspořádané (
def compare (x,y):if x < y: elif x > y: else:
Podmínky jsou zkoumány jedna za druhou. Je-li první nepravdivá, prověřuje se další. Je-li některá pravdivá, provede se bezprostředně následující větev programu. Jestliže je pravdivých podmínek více, provede se jen první z nich.
Procedura
Skladbu této procedury je nejlépe ukázat na konkretním příkladě:
def věk_skupiny (age):match age:case _ if age < 0: case _ if age <= 13: case _ if age < 19: case _ if age < 65: case _:
>>> print(věk_skupiny(25)) Dospělý
Jedna podmínka může být vnořena do druhé. Předchozí trojité větvení v odstavci 5.5.3 můžeme realizovat také takto:
def compare_imb (x,y):if x == y: else :if x < y: else :
>>> compare_imb(9,12) 9 is less than 12
Vnější podmínka má dvě větve. První větev obsahuje prostý příkaz k tisku. Druhá větev obsahuje
další podmínku
I když odsazení příkazů činí strukturu zápisu zřejmou, vnořené podmínky se velmi rychle stávají méně přehledné. Pokud můžeme, tak se jim raději vyhneme.
Vnořené podmínky můžeme často zjednodušit logickými operátory. Následující kód bude v další ukázce přepsán pro použití jen jedné podmínky:
def podm1 (x):if 0 < x: if x < 10:
K volání funkce
def podm2 (x):if 0 < x < 10:
Při splnění podmínky ukončí příkaz
def finito (x):for letter in "Python":if letter == x: break
finito('h') Current Letter: P Current Letter: y Current Letter: t
nebo:
var = 8while var > 0: var = var - 1if var == 5: break # ukončí provádění smyčky
Current var. value: 8 Current var. value: 7 Current var. value: 6 Adieu, var == 5
Při splnění podmínky přeruší příkaz
def contin (x):for letter in "Python":if letter == "h": continue
contin("h") Current Letter: P Current Letter: y Current Letter: t Jsme přerušeni! Current Letter: o Current Letter: n
nebo:
var = 6while var > 0: var = var - 1if var == 3: continue
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!
Touto často používanou vestavěnou funkcí zjistíme počet prvků iterovatelného objektu ze skupiny
>>>sg = "halelujah"# typ string >>> len (sg) 9 >>>bts = b'R\xc5\xaf\xc5\xbee'# typ bytes >>>len (bts) 6
Vestavěná funkce
range (n)# jen koncová mez range (m, n)# (start, stop) range (m, n, p)# (start, stop, krok)
vytvoří
Slovo potenciální označuje tu skutečnost, že místo celé zadané řady (celých) čísel se při deklaraci uloží pouze její parametry a k vlastnímu vytvoření této posloupnosti dojde až při jejím volání. Jedná se o případ takzvaného
Předností funkce range() je skutečnost, že zabírá stejné místo v paměti - bez ohledu na délku deklarované řady čísel.
Tuto posloupnost lze použít jako
>>>list (range (7))# chápáno jako range(0,7) [0, 1, 2, 3, 4, 5, 6] >>>tuple (range (2,7))# tuple je naše entice (2, 3, 4, 5, 6) >>>set (range (0,7,2)) {0, 2, 4, 6} >>>bytes (range (0,7,2)) b'\x00\x02\x04\x06' >>>list (range (7,5))# bez vhodného kroku vždy prázdný [] >>>list (range (7,0,-3))# vida [7, 4, 1]
Obrácenou posloupnost lze vytvořit i bez obrácených mezí a záporného kroku pomocí funkce
>>>list (reversed (range (7))) [6, 5, 4, 3, 2, 1, 0] >>>list (reversed (range (0,7,2))) [6, 4, 2, 0]
Objekt typu range je indexovatelným (subscriptable) objektem. Jeho elementy jsou individuálně přístupné uvedením indexu v hranaté závorce i metodou
>>>range (7)[2] 2 >>>range (7).__getitem__ (2) 2
Iterátor lze z objektu range vytvořit běžným způsobem funkcí
>>>for i in range(7): # eager iteration
>>>for number in range(20): # eager iteration if number%3 == 0:
Volání funkce enumerate(iterable, start=0) vrací objekt typu
>>>fruits = ('banana','apple','pear','grape')# iterábl >>>enum =enumerate (fruits)# iterátor >>>type (enum)# --> <class 'enumerate'>
Objekt typu
>>> enum[1]# TypeError: 'enumerate' object is not subscriptable
Přístup k prvkům iterátoru lze realizovat postupně prostřednictvím iterační funkce
>>>next (enum) (0, 'banana') >>> enum.__next__ () (1, 'apple') >>>for index in enum :# zbytek iterace
Jak vidno,
Funkci
>>>numbers = [2, 3, 4, 5] >>>for index, value in enumerate (numbers):
Všechny tyto tři funkce (vyššího řádu) pracují s iterovatelnými objekty (iterábly - viz 3.1) a produkují iterátory.
Funkce
Funkce filter() vrací iterátor, jenž musíme vhodným způsobem rozbalit, například funkcí
>>>ages = [7, 10, 16, 18, 26, 35]# iterábl >>>adults =filter (lambda x: x > 17, ages))# iterátor >>>list (adults))# nutno rozbalit Adults: [18, 26, 35]# Případně iterátor rozbalíme hned: >>>not_adults =tuple (filter(lambda x: x <= 17, ages)) >>>
Iterátor lze rozbalit i smyčkou for ... :
>>>for i in filter (lambda x: x % 2 == 0, ages):
Pro přetvoření iteráblu lze použít i formát predikátové funkce:
>>>ages = [7, 10, 16, 18, 26, 35] >>>def is_even (x):# predikát return x % 2 == 0# vrací True nebo False >>>set (filter (is_even, ages)), end='') {10, 16, 18, 26}
Argumentem pro parametr
Funkce map() aplikuje zadanou transformační funkci na každý element zadaného iteráblu (seznamu, entice, atp) a vrací sekvenci výsledků jako objekt
>>>numbers = 1, 2, 3, 4# iterábl >>>def squares (n):# transformační funkce return n*n >>>result =map (squares, numbers); result <map object at 0x000001AE79FA3460># objekt, který nutno rozbalit >>>result =list (map (l (squares, numbers)); result [1, 4, 9, 16]# objekt již rozbalený
Jiný příklad s funkcí lambda:
>>>num1 = [4, 5, 6]# Iteráblů lze zadat více než jeden. >>>num2 = [5, 6, 7]# Zřetězení funkcí list() a map(): >>>result =list (map (lambda x,y: x+y, num1, num2)); result# iterátor [9, 11, 13]
Rozbalení stringů do entic použitím funkce list() a tuple():
>>>tup = 'šach', 'mat', 'pat'# iterábl >>>test =list (map (tuple , tup))# rozbalený iterátor >>>
Funkce
Funkce zip(iterables) přijímá dvě či více iterovatelných sekvencí (iteráblů) a vytváří interní objekt typu
>>>izip =zip ([1, 2, 3], "postel", range(6)); izip <zip object at 0x000001E753183380># iterátor >>>list (izip) [(1, 'p', 0), (2, 'o', 1), (3, 's', 2)]# seznam # Iterátor je prázdný, nutno jej znovu deklarovat: >>>izip =zip ([1, 2, 3], "postel", range(1,5)) >>>set (izip) {(3, 's', 2), (2, 'o', 1), (1, 'p', 0)}# set # nebo sloučit deklaraci sekvence s deklarací iterátoru: >>>tuple (zip ([1, 2, 3], "postel", range(6))) ((1, 'p', 0), (2, 'o', 1), (3, 's', 2))# entice >>>dict (zip ([1, 2, 3, 4], "postel")) {1: 'p', 2: 'o', 3: 's', 4: 't'}# slovník
Počet entic ve výsledné sekvenci je dán počtem argumentů funkce zip. Délka výsledných entic je dána délkou nejkratšího argumentu. U slovníku mohou být pouze dva argumenty. Jeho enticemi jsou dvojice
Od verze
>>>set (zip ([1, 2, 3, 4], "postel", strict=True))ValueError: zip() argument 2 is longer than argument 1
Je nicméně možné vytvořit iterátor podle nejdelší vstupní sekvence a to pomocí funkce
>>>Souhrnná poznámkafrom itertools import zip_longest >>>numb = [1, 2, 3] >>>lett = ['a', 'b', 'c'] >>>long = range(5) >>>izip =zip_longest (numb, lett, long, fillvalue='#') >>>list (izip) [(1, 'a', 0), (2, 'b', 1), (3, 'c', 2), ('#', '#', 3), ('#', '#', 4)]
Výstupem z funkce
>>>izip =zip ([1, 2, 3], "postel", range(6)) >>>next (izip) (1, 'p', 0) >>>for i in izip: next (izip)# iterátor je prázdný Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration # Prázdný iterátor zaplníme opětovným voláním proměnné .izip
Interní objekt iterátoru lze také rozbalit funkcí
Funkce vyššího řádu
>>>from functools import reduce >>>seqv = 1,2,3,4# S funkcí pro dva argumenty: >>>def do_sum (x, y):return x + y >>>reduce (do_sum, seqv)--> 10 Případně s funkcí lambda: >>>reduce (lambda x,y: x+y , range(1,5))--> 10 Případně s hodnotou pro parametr >>>initial :reduce (do_sum, seqv, 12)--> 22
Funkce reduce() zde postupně provádí součty (((1+2)+3)+4), eventuelně (((12 (argument pro parametr initial) +1)+2)+3)+4).
Hodnota parametru 'initial' se při realizaci funkce reduce() zařadí na první pozici zpracovávané sekvence. Datové typy argumentů pro sekvenci i parametr 'initial' musejí být shodné.
Parametr initial je důležitý pro situaci, kdy by argument pro parametr iterable měl být prázdný. V tom případě by funkce
Inteligentní náhradou invokace
>>> sum(seqv) 10Pro sumaci řetězců (konkatenaci) lze použít tento výraz:
>>> from functools import reduce >>> faq = "pes", "kočka" >>> reduce(lambda x,y: x+y, faq, "sumace = ") 'sumace = peskočka'
Smyčky jsou často užívány v programech, které spočítají výsledek tak, že začnou s přibližnou hodnotou a opakovaným výpočtem výsledek zpřesňují.
Například, jedním ze způsobů počítání druhé odmocniny čísla je Newtonova metoda. Při určení odmocniny čísla
better = (approx + n/approx) / 2
Výpočet se opakuje tak dlouho, až se zpřesněná hodnota téměř neliší od předchozí. Pro provádění výpočtu napíšeme funkci:
def sqrt (n): approx = n/2.0 better = (approx + n/approx)/2.0while better != approx: approx = better better = (approx + n/approx)/2.0return approx
Volejme funkci pro argument
Newtonova metoda je příkladem algoritmu - obecného řešení určitého problému (v našem případě počítání druhé odmocniny).
Napište definice funkcí s invokacemi v zadaných doctestech. Všechny příklady zapisujte do samostatných souborů ve složce
Příklady s doctestem budou mít na konci skriptu tento kód:
if __name__ == '__main__': import doctest doctest.testmod()
Tyto příklady řešte až po prostudování textu v kap. 3.10.
def compare (a, b): """ >>> compare(5,4) 1 >>> compare(7,7) 0 >>> compare(2,3) -1 """# Zde napište tělo funkce
def hypo (a,b): """ >>> hypo(3,4) 5.0 >>> hypo(12,5) 13.0 >>> hypo(7,24) 25.0 """# tělo funkce může mít pouhé 2 řádky
def slope (x1,y1,x2,y2): """ >>> slope(5,3,4,2) 1.0 >>> slope(1,2,3,2) 0.0 >>> slope(1,4,1,2) kolmice k ose 'x'Ošetřená výjimka! >>> slope(2,4,1,2) 2.0 """# Zde napište tělo funkce
Napište funkci
def intercept (x1,y1,x2,y2): """ >>> intercept(1,6,3,12) 3.0 >>> intercept(6,1,1,6) 7.0 >>> intercept(4,6,12,8) 5.0 """# Zde napište tělo funkce
def is_multiple( (m,n): """ >>> is_multiple(12,3) True >>> is_multiple(12,4) True >>> is_multiple(12,5) False """# Zde napište tělo funkce
Napište fci
def is_divisible( (m,n): """ >>> is_divisible(20,4) True >>> is_divisible(21,8) False """# Zde napište tělo funkce
Při řešení použijete podmínky if ... :, else: a vyberete si jeden z existujících způsobů dělení: normální a/b, celočíselné a//b nebo dělení se zbytkem (modulo) a%b.
def fah2cel (t): """ >>> fah2cel(212) 100 >>> fah2cel(32) 0 >>> fah2cel(-40) -40 >>> fah2cel(37) 3 """# Zde napište tělo funkce
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |