Linux E X P R E S

Facebook

Python 3 (5): cykly while a for

python.png

Dnes sa budeme zaoberať opakovaním. Ukážeme si, ako a kedy používať cykly while a for, oboznámime sa s použitím príkazov break a continue a nezabudneme ani na zaujímavé funkcie range a enumerate.


Cyklus nám Slovník súčasného slovenského jazyka vysvetľuje ako ustálený rad činností, procesov, javov, zmien pravidelne sa opakujúcich v určitých intervaloch. To isté pre cykly platí aj v programovaní. Cykly používame, pokiaľ chceme vykonávať nejakú činnosť viackrát za sebou. V Pythone máme dva typy cyklov a to takzvaný while a for cyklus, a každému typu sa budem v tejto časti venovať zvlášť.

Príklad, ako by to nemalo vyzerať:

print(1)
print(2)
print(3)
print(4)
print(5)

Použitie cyklu while – takto je to už lepšie:

i = 1
while i<=5:
    print(i)
    i += 1

… alebo takto (cyklus for):

for i in range(1, 6):
    print(i)

Vo všetkých prípadoch dostaneme rovnaký výstup – výpis čísiel od 1 po 5 (vrátane), ale vidíme, že spôsob zápisu programu je rozdielny.

Cyklus while

Štruktúra cyklu while sa skladá z bloku while a voliteľného bloku else:

while expression:
    #do something
else:
    #do something else

Za kľúčovým slovom nasleduje výraz (napríklad x > 2) alebo premenná s pravdivostnou hodnotou True/False. Else blok je voliteľný a jeho význam je rovnaký ako pri podmienkach. Ak výraz za while prestane byť pravdivý, cyklus sa zastaví a vykoná sa blok else. Celý cyklus while sa dá prečítať takto: „Pokiaľ platí výraz, rob toto: … Inak urob toto.“ Jednoduchý príklad pre použitie cyklu while som spomenul už vyššie, teraz skúsme niečo ovplyvnené vstupom od užívateľa.

count = 0
a = 0
while not(a > 100):
    a = int(input("Zadajte číslo väčšie ako 100: "))
    count += 1
else:
    print("Gratulujem!")
    print("Na {}. pokus sa vám podarilo zadať správne číslo.".format(count))

Tento program od vás bude žiadať číslo väčšie ako 100, až kým ho nezadáte, a potom vám napíše, na koľký raz ste zadali žiadané číslo. Výstup môže vyzerať napríklad takto:

$ python while.py
Zadajte číslo väčšie ako 100: 42      
Zadajte číslo väčšie ako 100: 100
Zadajte číslo väčšie ako 100: 101997296
Gratulujem!
Na 3. pokus sa vám podarilo zadať správne číslo.

Nekonečný cyklus, break a continue

while True:
    print("!> " + input("?> "))

Výstup:

$ python echo.py
?> Ahoj!
!> Ahoj!
?> Maj sa 
!> Maj sa
?> ^CTraceback (most recent call last):
  File "echo.py", line 2, in <module>
    print("!> " + input("?> "))
KeyboardInterrupt

Keďže sa v tomto prípade cyklus sám nikdy nevypne, pretože výraz True bude vždy pravdivý, musíme celý program násilne ukončiť napríklad klávesovou skratkou CTRL+C. Ďalšou možnosťou je v takomto cykle použiť príkaz break, ktorý daný cyklus zastaví.

while True:
    inp = input("?> ")
    if inp == "STOP!":
        break
    print("!> " + inp)
else:
    print("Au!")

print("Maj sa.")
Výstup:
$ python echo.py
?> 7
!> 7
?> asd
!> asd
?> STOP!
Maj sa.

Do cyklu sme teraz vložili podmienku, ktorá nám ho zastaví, pokiaľ náš vstup bude „STOP!“. Môžete si všimnúť, že pri použití break sa nevykoná kód v else bloku.

Ďalším dostupným príkazom v cykloch je príkaz continue. Tento príkaz na rozdiel od break nezastaví celý cyklus, ale len práve vykonávaný blok, a pokiaľ je výraz pre cyklus naďalej pravdivý, blok sa opätovne vykoná. Pre ukážku znovu upravíme a použijeme program, ktorý chce číslo väčšie ako 100:

count = 0
a = 0
while not(a > 100):
    a = int(input("Zadajte číslo väčšie ako 100: "))
    if a == 99:
        continue
    count += 1
else:
    print("Gratulujem!")
    print("Na {}. pokus sa vám podarilo zadať správne číslo.".format(count))

Výstup:

$ python while.py
Zadajte číslo väčšie ako 100: 99 
Zadajte číslo väčšie ako 100: 99
Zadajte číslo väčšie ako 100: 99
Zadajte číslo väčšie ako 100: 99
Zadajte číslo väčšie ako 100: 101
Gratulujem!
Na 1. pokus sa vám podarilo zadať správne číslo.

Teraz sme pridaním podmienky „pokiaľ je zadané číslo rovné 99, pokračuj od začiatku“ spôsobili, že zadaním čísla 99 preskočíme riadok count += 1, ktorý počíta pokusy. Preto vidíme, že aj keď sme 4krát po sebe zadali číslo 99 a až na 5. pokus sme zadali číslo väčšie ako 100 (101), program nám vypíše, že sa nám to podarilo na prvý pokus.



Cyklus for

Tento druh cyklu sa používa väčšinou na postupné prechádzanie iteračnými dátovými typmi - listami, setmi, reťazcami alebo inými objektami obsahujúcimi viacej zoradených položiek. Jeho štruktúra vyzerá takto:

for i in x:
    #do something
else:
    #do something else

Funkcia cyklu for spočíva v tom, že postupne prechádza položkami v objekte x, a pre každý cyklus uloží obsah jednej do premennej i. S premennou i sa ďalej v cykle môže rôzne manipulovať. Blok else je znovu voliteľný, pričom jeho obsah sa vykoná v prípade, že cyklus dôjde na koniec objektu x. Uvedieme si jednoduchý príklad:

numbers = [-54, 88, 2, -99, 5]
for i in numbers:
    print(i)
else:
    print("Koniec.")
Výstup:
$ python for.py
-54
88
2
-99
5
Koniec.

V cykle for je takisto možné použiť príkazy breakcontinue, ktoré fungujú rovnako ako pri cykle while. Pri použití break sa cyklus zastaví a nevykoná sa else blok a continue spôsobí, že sa aktuálny cyklus cyklu zastaví a cyklus pokračuje ďalšou položkou. Príklad:

string = 'A on povedal, "prídem neskôr." A neprišiel.'
string_new = ''
for char in string:
    if char == '"':
        continue
    string_new += char
    if char == '.':
        break
else:
    print('Koniec.')
print(string_new)

Výstup:

$ python for.py 
A on povedal, prídem neskôr.

range()

Cyklus for sa často využíva na vykonanie nejakej časti kódu viackrát bez toho, aby v nej dochádzalo k nejakej zmene použitých údajov. Samozrejme pre takýto účel sa dá jednoducho využiť aj cyklus while, no cyklus for je o niečo rýchlejší a zároveň kratší. Spolu s cyklom for je obvyklé použitie funkcie range(), ktorá vyžaduje minimálne 1 a maximálne 3 argumenty, a podľa nich vytvára objekt s určitým počtom číselných položiek. Ukážka na komentovanom príklade:

>>> range(8) # == range(0, 8)
range(0, 8)
>>> list(range(8)) # vytvorí list s číslami 0 až 7 (vrátane)
[0, 1, 2, 3, 4, 5, 6, 7]
>>> tuple(range(8, 15)) # vytvorí n-ticu s číslami 8 až 14
(8, 9, 10, 11, 12, 13, 14)
>>> set(range(8, 15, 2)) # vytvorí list s číslami 8 až 14 s krokom 2
{8, 10, 12, 14}

Pri použití v cykle for tak vlastne vytvorí jednoduchý rozsah určitej dĺžky – počet cyklov. Príklad použitia som uviedol už v úvode článku, kedy som pomocou cyklu for a funkcie range vypísal čísla od 1 po 5. Teraz uvediem primitívny príklad pre porovnanie s cyklom while:

Cyklus for:

for i in range(3):
    print("...")

Cyklus while:

i = 0
while i < 3:
    print("...")
    i += 1

Výstup oboch:

$ python [for0.py/while0.py]
...
...
...

Vidíme, že pre cyklus for nám stačili 2 riadky, v ktorých sa nachádzalo: „Pre i v rozsahu 0 až 3 (spolu 3 položky) vypíš "...".“ Cyklus while potreboval riadky 4:  „Premenná i je 0. Pokiaľ je i menšie ako 3, vypíš "..." a k i pripočítaj 1.“

enumerate()

Ďalšia zaujímavá funkcia, ktorá je užitočná napríklad, keď chceme meniť obsah listu, ktorým cyklus práve prechádza. Funkcia enumerate() vytvorí nový objekt s indexom pre každú položku a danou položkou v liste. Príklad:

>>> nums = [9, 2, 6, 77, 23, 0]
>>> enumerate(nums)
<enumerate object at 0x7fc6bff22090>
>>> list(enumerate(nums))
[(0, 9), (1, 2), (2, 6), (3, 77), (4, 23), (5, 0)]

Pri použití v cykle for potom nevytvárame len jednu, ale dve premenné, pričom jedna obsahuje index položky a druhá samotnú položku. Príklad použitia:

nums = [55, 4, 33, 9, 8, 42, 6, 19, 0]
for i, item in enumerate(nums):
    if item < 10:
        nums[i] = 99
print(nums)

Výstup:

$ python enumerate.py
[55, 99, 33, 99, 99, 42, 99, 19, 99]

Do premennej i bol ukladaný index čísla v premennej item v premennej nums. Pokiaľ bolo číslo menšie ako 10, položka bola prepísaná na číslo 99.

Záver

Samozrejme, nezabudnime na náš jednoduchý program pre výpočet objemu a obsahu kocky a jeho postupné vylepšovanie. Po dnešnom dieli môžeme náš program vylepšiť o cyklus while True tak, aby sa po neplatnom vstupe od užívateľa neukončil, ale znovu požadoval vstup.

#!/usr/bin/env python3
while True:
    inp = input("Zadajte dĺžku strany kocky (bez jednotiek): ")
    try:
        a = float(inp)
    except ValueError:
        print("Neplatný vstup. Zadávajte čísla.")
        continue

    if 0 > a:
        print("Neplatný vstup. Zadávajte kladné čisla.")
        continue
    break

volume = a**3
surface_area = 6*a**2
print("Objem kocky je: {}".format(volume))
print("Príklad: {a}^3={result}".format(a=a, result=volume))
print("Povrch kocky je: {}".format(surface_area))
print("Príklad: 6×{a}^2={result}".format(a=a, result=surface_area))

Okrem toho som namiesto prevádzania vstupu na celé číslo (integer) použil prevod na desatinné číslo (float), takže náš program vie odteraz počítať aj s takýmito číslami.

Ukážka fungovania vylepšenej verzie Ukážka fungovania vylepšenej verzie

V nasledujúcom diele sa pozrieme na funkcie, do ktorých budeme baliť jednotlivé časti programov a neskôr ich volať s rôznymi argumentami.

Diskuze (0) Nahoru