Martin Svoboda

Martin Svoboda - Blog

Cykly 5: vnořené cykly


Vnořené cykly nejsou ničím novým z technického hlediska, jde o cykly uvnitř jiných cyklů. Vnořené cykly mohou být celkem nepřehlednou konstrukcí a zároveň často používanou. Bývají často problematiké pro začátečnky, ale čím dříve nad nimi začneč přemýšlet tím dříve se do toho dostaneš.

Struktura vnořeného cyklu

Co je to vnořený cyklus?

Vnořený cyklus je cyklus, který běží uvnitř jiného cyklu. To znamená, že vnitřní cyklus je opakovaně prováděn pro každou iteraci vnějšího cyklu. Následující příklad ilustruje jednoduchý vnořený cyklus, kde oba cykly probíhají pětkrát:

for i in range(5):     # vnější cyklus
    for j in range(5): # vnitřní cyklus
        print(f"i = {i}, j = {j}")
    print("Konec vnitřního cyklu.")
print("Konec vnějšího cyklu.")

Tento příklad vypíše hodnoty proměnných i a j pro každý průchod cyklem. Vnější cyklus běží od 0 do 4 a pro každou hodnotu i vnitřní cyklus také proběhne od 0 do 4. Takže celkem se vypíše 25 kombinací hodnot i a j.

Jak fungují provázané vnořené cykly?

Provázanost cyklů znamená, že chování vnitřního cyklu závisí na proměnné vnějšího cyklu. Následující příklad ukazuje, jak vnitřní cyklus začíná od hodnoty i vnějšího cyklu:

for i in range(5):        # vnější cyklus
    for j in range(i, 5): # vnitřní cyklus
        print(f"i = {i}, j = {j}")
    print("Konec vnitřního cyklu.")
print("Konec vnějšího cyklu.")

Tento příklad vypíše méně kombinací, protože vnitřní cyklus začíná vždy od aktuální hodnoty i vnějšího cyklu, což vede k tomu, že se iterace postupně zkracují.

Následující příklad ukazuje, jak pomocí vnořených cyklů vykreslit jednoduchý trojúhelníkový vzor:

for i in range(5):
    for j in range(i + 1):
        print("*", end="")
    print()

Výstup bude následující:

*
**
***
****
*****

Kontrola duplicitních písmen

V následujícím příkladu využíváme vnořený cyklus pro zjištění, zda se v textu vyskytují nějaké písmeno vyskytuje vícekrát:

text = "Dobrý den, jak se máte?"
ne_pismena = " ,.?!-"
for i in range(len(text)):
    if text[i] in ne_pismena: continue
    for j in range(i + 1, len(text)):
        if text[j] in ne_pismena: continue
        if text[i] == text[j]:
            print(f"Nalezena duplicita: {text[i]}")

Všimni si, že kombinujeme znalosti z každé části kurzu. V nořený cyklus jde vždy od indexu dalšího písmena v textu, kdyby začínal dříve, tak by kontroloval stejné části textu. Vnořené smyčky se běžně používají při práci s vícerozměrnými datovými strukturami, jako jsou seznamy seznamů, matice nebo mřížky.

Zde jsem ukázel vnořené pouze dva cykly v sobě, ale můžeš jich vnořit kolik chceš, ale uroveň nepřehlednosti a nepochopitelnost poroste strmě nahoru.

Vnořené bloky kódu včetně vnořených cyklů mohou značně přispívat k nepřehlednosti kódu nebo ke složitému pochopení. Někdy je to ovšem jediné nebo nejlepší možné řešení je proto dobré dodržovat pár pravidel:

  1. Používejte smysluplné komentáře: Komentáře pomohou ostatním (a i vám samotným) pochopit, co kód dělá.
  2. Udržujte úrovně vnoření minimální: Čím více úrovní cyklů máte, tím je kód méně čitelný. Pokuste se omezit vnořování na 1-2 úrovně.

Kontrolní otázky

Pokud dokážete odpovědět na následující otázky, jste na dobré cestě k pochopení vnořených cyklů:

  1. Co je vnořená smyčka?
  2. Jak lze vnořené smyčky využít v programování?
  3. Na co si musíte dát pozor při používání vnořených cyklů?
  4. Kolikrát je v následujícím kódu vypsán řetězec “Ahoj”?
for i in range(3):
    for j in range(2):
        print("Ahoj")

Kvízy

Kvíz:

Co je to vnořená smyčka v jazyce Python?

  1. Smyčka, která probíhá pouze jednou v rámci jiné smyčky.
  2. Smyčka, která iteruje nad dvěma různými seznamy současně.
  3. Smyčka, která je definována uvnitř jiné smyčky.
  4. Smyčka, která se může provést pouze tehdy, pokud předchozí smyčka dokončila své provádění.
Kvíz:

Jaký je výstup tohoto kódu?

    for i in range(3):
        for j in range(2):
       	    print(i, j)
  1. 0 0 
    1 1 
    2 2
  2. 0 1 2 
    0 1 2
  3. 0 0 
    1 0 
    2 0 
    0 1 
    1 1 
    2 1
  4. 0 0 
    0 1 
    1 0 
    1 1 
    2 0 
    2 1

Cvičení

1. Čtvercový vzor

Napište program v jazyce Python, který pomocí dvou vnořených cyklů vypíše vzor hvězdiček (*) ve tvaru čtverce. Program by se měl uživatele zeptat na velikost čtverce (počet hvězdiček na každé straně) a poté vypsat čtverec. Pokud například uživatel zadá 5, program by měl vypsat:

*****
*****
*****
*****
*****

2. Trojúhelníkový vzor

Nyn í upravte program, který jste napsali pro čtvercový vzor, tak, aby vytiskl pravoúhlý trojúhelník. Pokud uživatel zadá například 5, program by měl vypsat:

*
**
***
****
*****

3. Tabulka násobení

Napište program, který pomocí vnořených smyček vypíše tabulku násobení. Vnější smyčka by měla iterovat přes čísla 1 až 10 a vnitřní smyčka by měla iterovat přes čísla 1 až 10 pro každé číslo ve vnější smyčce. Program by měl vypsat každou operaci násobení a její výsledek. Prvních několik řádků výstupu může vypadat například takto:

1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
...
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
...

A tak dále až do 10 x 10 = 100.

4. Prvočísla

Prvočíslo je číslo, které nemá jiné dělitele než 1 a samo sebe. Napište program v jazyce Python, který pomocí vnořených smyček najde všechna prvočísla od 1 do n, kde n je číslo zadané uživatelem. Vnější smyčka by měla iterovat přes čísla od 1 do n a vnitřní smyčka by měla zkontrolovat, zda aktuální číslo z vnější smyčky nemá jiné dělitele než 1 a samo sebe.