Zagnieżdżone pętle
Co to jest zagnieżdżona pętla?
Zagnieżdżona pętla to po prostu „pętla w pętli” — jedna pętla (zewnętrzna) zawiera w swoim ciele drugą pętlę (wewnętrzną). Używamy jej, gdy chcemy przechodzić po strukturze dwuwymiarowej, np. po wierszach i kolumnach siatki, tablicy lub przy rysowaniu wzorów.
Najważniejsze zasady — krok po kroku
- Za każdym razem, gdy zewnętrzna pętla wykonuje jedną iterację, wewnętrzna pętla wykonuje wszystkie swoje iteracje od początku do końca.
- Jeśli zewnętrzna ma n iteracji, a wewnętrzna m, to łącznie wykonanych zostanie n × m iteracji ciała wewnętrznej pętli.
- Zagnieżdżone pętle są przydatne przy: rysowaniu prostokątów i wzorów, tworzeniu tablic (macierzy), sprawdzaniu wszystkich par elementów (kombinacje) czy generowaniu tabliczki mnożenia.
- Uwaga na indeksy: w Pythonie często zaczynamy od 0 (range(n) daje 0..n-1). To wpływa na warunki, gdy porównujemy pozycje (np. przekątna).
Krótka wizualizacja
Wyobraź sobie tabelkę z wierszami (i) i kolumnami (j). Pętla zewnętrzna przechodzi po wierszach, a w każdej iteracji tej pętli pętla wewnętrzna przechodzi po wszystkich kolumnach tego wiersza.
Przykłady z objaśnieniami
Przykład 1 — trójkąt z gwiazdek (opis krok po kroku)
- Zmienna n określa, ile wierszy ma mieć trójkąt.
- W zewnętrznej pętli i przyjmuje wartości od 1 do n — numer aktualnego wiersza.
- W wewnętrznej pętli drukujemy gwiazdki tyle razy, ile wynosi numer wiersza (i), dzięki czemu każdy kolejny wiersz ma o jedną gwiazdkę więcej.
- Po zakończeniu każdej wewnętrznej pętli wywołujemy print(), żeby przejść do nowej linii.
Kod:
n = 5
for i in range(1, n+1): # i = 1, 2, 3, 4, 5
for j in range(i): # dla i=3 -> j = 0,1,2 (czyli 3 gwiazdki)
print("*", end="") # drukuj gwiazdkę bez nowej linii
print() # po wewnętrznej pętli przejdź do nowego wiersza
Wynik (dla n = 5):
*
**
***
****
*****
Przykład 2 — tablica mnożenia 1–5 (z wyjaśnieniem)
- Zewnętrzna pętla przechodzi po wierszach (wartościach od 1 do 5), wewnętrzna po kolumnach (również 1–5).
- W ciele drukujemy iloczyn i*j, a po każdym wierszu przechodzimy do następnej linii.
Kod:
for i in range(1, 6):
for j in range(1, 6):
print(i*j, end="\t") # \t dodaje tabulator, by kolumny były czytelne
print()
Wynik to macierz z iloczynami od 1 do 5 w wierszach i kolumnach.
Typowe błędy i wskazówki do debugowania
- Pamiętaj o wcięciach — w Pythonie wcięcia określają, która instrukcja należy do której pętli.
- Uważaj na używanie tej samej nazwy zmiennej dla obu pętli. Zewnętrzna i wewnętrzna powinny mieć różne nazwy (np. i, j).
- Jeśli otrzymujesz za dużo lub za mało znaków w wierszu, sprawdź zakresy w range() (czy zaczynasz od 0 czy od 1?).
- Jeśli potrzeba formatowania kolumn, użyj tabulatora lub formatowania łańcuchów (f-strings) z określoną szerokością.
Złożoność
Jeśli zewnętrzna pętla wykonuje n iteracji, a wewnętrzna m, to liczba operacji rośnie jak n × m — warto o tym pamiętać przy dużych n i m.
Zadanie (bez gotowego rozwiązania)
Napisz program, który dla podanej liczby n tworzy kwadrat n×n, w którym na przekątnej znajduje się znak 'X', a pozostałe pola to kropki ('.').
Wskazówki:
- Użyj dwóch pętli: zewnętrzna po wierszach (np. i od 0 do n-1), wewnętrzna po kolumnach (j od 0 do n-1).
- Pomyśl, jak rozpoznać, że dana pozycja (wiersz i, kolumna j) leży na przekątnej. (Zastanów się, jaka jest zależność między numerem wiersza i numerem kolumny dla przekątnej.)
- Wypisuj znak bez przechodzenia do nowej linii w obrębie wewnętrznej pętli, a po jej zakończeniu dodaj drukowanie nowego wiersza.
- Możesz użyć poniższego szkicu i dodać w nim swoje warunki:
Szkielet programu:
n = int(input("Podaj n: "))
for i in range(n):
for j in range(n):
# zdecyduj, co wypisać w zależności od i i j
pass
# po zakończeniu wewnętrznej pętli przejdź do nowego wiersza
Zachęcam do spróbowania samodzielnego uzupełnienia tego szkicu. Jeśli utkniesz, napisz, co próbowałeś — chętnie podpowiem następne kroki lub sprawdzę błędy bez podawania gotowego kodu.