← Strona główna

04 — Pętle for

Iterowanie po sekwencjach, range(), enumerate(), pętle zagnieżdżone, break i continue.

Struktury i pętle

1. Jak działa pętla for?

Pętla for służy do iterowania — czyli wykonywania tego samego bloku kodu dla każdego elementu sekwencji. Sekwencją może być lista, tekst, krotka, zakres range() i inne.

  • Przy każdym obrocie pętli zmienna iterująca przyjmuje kolejną wartość z sekwencji
  • Ciało pętli jest wcięte — 4 spacje lub Tab
  • Pętla kończy się automatycznie po wyczerpaniu sekwencji
  • Zmienna iterująca jest dostępna po zakończeniu pętli (ma ostatnią wartość)
Schemat for zmienna in sekwencja:
    # ciało pętli
Przykład — podstawy pętli for
# Iterowanie po liście
owoce = ["jabłko", "gruszka", "śliwka"]
for owoc in owoce:
    print(owoc)
# jabłko
# gruszka
# śliwka

# Iterowanie po tekście
for litera in "Python":
    print(litera, end=" ")
# P y t h o n

# Iterowanie po krotce
for liczba in (1, 2, 3, 4, 5):
    print(liczba ** 2, end=" ")
# 1 4 9 16 25

# Zmienna po pętli
for i in [10, 20, 30]:
    pass
print(i)   # 30 — ostatnia wartość

2. Funkcja range()

range() generuje sekwencję liczb całkowitych. To najczęstszy sposób sterowania liczbą powtórzeń pętli.

WywołanieGeneruje
range(5)0, 1, 2, 3, 4
range(2, 7)2, 3, 4, 5, 6
range(0, 10, 2)0, 2, 4, 6, 8
range(10, 0, -1)10, 9, 8, ..., 1
range(5, -1, -1)5, 4, 3, 2, 1, 0
Uwaga — stop jest wykluczony range(1, 6) daje 1, 2, 3, 4, 5 — bez 6. Żeby uzyskać liczby od 1 do n włącznie, piszesz range(1, n+1).
Przykład — range() w pętlach
# Podstawowe użycie
for i in range(5):
    print(i, end=" ")       # 0 1 2 3 4

# Od 1 do 10
for i in range(1, 11):
    print(i, end=" ")       # 1 2 3 4 5 6 7 8 9 10

# Co drugi — liczby parzyste
for i in range(0, 21, 2):
    print(i, end=" ")       # 0 2 4 6 8 10 12 14 16 18 20

# Odliczanie
for i in range(5, 0, -1):
    print(i, end=" ")       # 5 4 3 2 1
print("Start!")

# Indeksowanie listy przez range
kolory = ["red", "green", "blue"]
for i in range(len(kolory)):
    print(f"{i}: {kolory[i]}")

3. enumerate() i zip() w pętli for

enumerate(sekwencja, start=0) — gdy potrzebujesz jednocześnie indeksu i wartości. Eliminuje potrzebę ręcznego licznika.

zip(a, b, c...) — łączy kilka sekwencji w pary (lub trójki itd.). Pętla kończy się gdy skończy się najkrótsza sekwencja.

  • enumerate(lista) — indeksy od 0
  • enumerate(lista, 1) — indeksy od 1
  • zip(a, b) — pary elementów z dwóch list
  • zip(a, b, c) — trójki z trzech list
Rozpakowywanie krotek W pętli for i, val in enumerate(lista) Python automatycznie rozpakowuje parę (i, val) — nie musisz pisać [0] i [1].
Przykład — enumerate i zip
# enumerate — indeks i wartość
produkty = ["mleko", "chleb", "masło"]

for i, produkt in enumerate(produkty):
    print(f"{i}: {produkt}")
# 0: mleko  1: chleb  2: masło

for i, produkt in enumerate(produkty, 1):
    print(f"{i}. {produkt}")
# 1. mleko  2. chleb  3. masło

# zip — dwie listy równocześnie
imiona = ["Kasia", "Marek", "Zofia"]
oceny  = [5, 4, 3]

for imie, ocena in zip(imiona, oceny):
    print(f"{imie} → {ocena}")

# zip trzech list
miasta  = ["Kraków", "Gdańsk", "Poznań"]
temp    = [22, 18, 20]
pogoda  = ["słonecznie", "pochmurno", "deszczowo"]

for miasto, t, p in zip(miasta, temp, pogoda):
    print(f"{miasto}: {t}°C, {p}")

4. Sterowanie pętlą — break, continue, else

break — natychmiast kończy pętlę i przechodzi do kodu za nią.

continue — pomija resztę aktualnego obrotu i przechodzi do następnego.

else przy for — blok else wykonuje się gdy pętla zakończyła się normalnie (bez break).

  • break — przerwij całą pętlę
  • continue — pomiń ten obrót, idź dalej
  • else — "pętla skończyła się bez przerwania"
  • W pętlach zagnieżdżonych break przerywa tylko wewnętrzną pętlę
for...else na egzaminie Klasyczne użycie: szukasz elementu w liście — jeśli pętla doszła do końca bez break, element nie istnieje → blok else to obsługuje.
Przykład — break, continue, else
# break — zatrzymaj pętlę
for i in range(10):
    if i == 5:
        break
    print(i, end=" ")
# 0 1 2 3 4

# continue — pomiń dany obrót
for i in range(10):
    if i % 2 == 0:
        continue
    print(i, end=" ")
# 1 3 5 7 9  (tylko nieparzyste)

# for...else — szukanie elementu
szukana = 7
liczby = [3, 5, 2, 8, 1]

for l in liczby:
    if l == szukana:
        print(f"Znalazłam {szukana}!")
        break
else:
    print(f"Nie ma liczby {szukana}.")
# Nie ma liczby 7.

5. Pętle zagnieżdżone

Pętla wewnętrzna wykonuje się w całości dla każdego obrotu pętli zewnętrznej. Jeśli zewnętrzna ma n obrotów, a wewnętrzna m — łącznie wykonuje się n × m obrotów.

  • Typowe zastosowania: tablice 2D, tabliczka mnożenia, wzory z gwiazdek
  • Każda pętla ma swoją zmienną iterującą — zazwyczaj i, j, k
  • break w pętli wewnętrznej przerywa tylko wewnętrzną
  • Głęboka zagnieżdżoność (3+) utrudnia czytanie — rozważ funkcję
Złożoność obliczeniowa Dwie pętle zagnieżdżone po n elementów = O(n²). Dla dużych danych to ważne — algorytmy O(n²) są wolniejsze niż O(n log n).
Przykład — pętle zagnieżdżone
# Tabliczka mnożenia 5x5
for i in range(1, 6):
    for j in range(1, 6):
        print(f"{i*j:3}", end="")
    print()   # nowa linia po każdym wierszu
#   1  2  3  4  5
#   2  4  6  8 10
#   3  6  9 12 15 ...

# Wzór trójkąta z gwiazdek
for i in range(1, 6):
    print("*" * i)
# *
# **
# ***
# ****
# *****

# Przejście przez listę list (macierz)
macierz = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
for wiersz in macierz:
    for element in wiersz:
        print(element, end=" ")
    print()

6. List comprehension — pętla w jednej linii

List comprehension to skrócony zapis tworzenia listy za pomocą pętli. Czytelniejszy i szybszy niż pętla z append().

  • Podstawowy: [wyrażenie for x in sekwencja]
  • Z warunkiem: [wyrażenie for x in sekwencja if warunek]
  • Można zagnieżdżać — ale traci na czytelności
  • Wynik to zawsze nowa lista
Kiedy używać? Gdy tworzysz nową listę przez transformację lub filtrowanie istniejącej. Gdy logika jest prosta i mieści się w jednej linii. Dla złożonej logiki — zwykła pętla jest czytelniejsza.
Przykład — list comprehension
# Zwykła pętla vs list comprehension
kwadraty = []
for x in range(1, 6):
    kwadraty.append(x ** 2)

# To samo krócej:
kwadraty = [x ** 2 for x in range(1, 6)]
print(kwadraty)   # [1, 4, 9, 16, 25]

# Z warunkiem — tylko parzyste
parzyste = [x for x in range(20) if x % 2 == 0]
print(parzyste)   # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# Transformacja tekstu
slowa = ["python", "java", "rust"]
wielkie = [s.upper() for s in slowa]
print(wielkie)    # ['PYTHON', 'JAVA', 'RUST']

# Filtrowanie — słowa dłuższe niż 4 znaki
dlugie = [s for s in slowa if len(s) > 4]
print(dlugie)     # ['python']

# Liczby z listy tekstów
teksty = ["1", "2", "abc", "3", "xyz"]
liczby = [int(t) for t in teksty if t.isdigit()]
print(liczby)     # [1, 2, 3]

Zadania przykładowe z omówieniem

Zadanie 1 Tabliczka mnożenia — wybrana liczba łatwe

Wczytaj liczbę całkowitą od 1 do 10. Wypisz jej tabliczkę mnożenia od 1 do 10 w czytelnym formacie: 3 × 4 = 12.

Rozwiązanie
n = int(input("Podaj liczbę (1-10): "))

for i in range(1, 11):
    wynik = n * i
    print(f"{n} × {i:2} = {wynik:3}")
Omówienie krok po kroku
  1. range(1, 11)
    Generuje liczby od 1 do 10 włącznie. Stop wynosi 11 bo zakres jest wyłącznyrange(1, 11) daje 1, 2, ..., 10.
  2. Formatowanie {i:2} i {wynik:3}
    :2 oznacza pole szerokości 2 znaków — jednocyfrowe liczby dostaną spację przed sobą. Dzięki temu kolumny są równe.
  3. Obliczenie wewnątrz pętli
    wynik = n * i liczy się przy każdym obrocie — i przyjmuje kolejno 1, 2, 3... aż do 10.
Zadanie 2 Zliczanie samogłosek w tekście łatwe

Wczytaj zdanie od użytkownika. Policz ile jest w nim samogłosek (a, e, i, o, u, y — duże i małe). Wypisz liczbę samogłosek i wypisz je wszystkie.

Rozwiązanie
zdanie    = input("Wpisz zdanie: ")
samogloski = "aeiouąęóAEIOUĄĘÓyY"

licznik   = 0
znalezione = []

for znak in zdanie:
    if znak in samogloski:
        licznik += 1
        znalezione.append(znak)

print(f"Liczba samogłosek: {licznik}")
print(f"Samogłoski: {' '.join(znalezione)}")
Omówienie krok po kroku
  1. Iterowanie po znakach tekstu
    for znak in zdanie — tekst jest sekwencją, pętla pobiera po jednym znaku. Nie potrzebujemy indeksów.
  2. Operator in dla tekstu
    znak in samogloski sprawdza czy znak należy do łańcucha. To działa tak samo jak sprawdzanie elementu w liście.
  3. Licznik i lista jednocześnie
    licznik += 1 zlicza, znalezione.append(znak) zbiera konkretne litery. Dwa różne cele, jeden warunek.
  4. join() do wypisania listy
    ' '.join(znalezione) łączy elementy listy w jeden tekst, rozdzielając spacjami — czytelniejsze niż print(znalezione).
Zadanie 3 Piramida liczb średnie

Wczytaj liczbę n (np. 5). Wypisz piramidę liczb: w pierwszym wierszu 1, w drugim 1 2, w trzecim 1 2 3 itd., aż do n wierszy.

Rozwiązanie
n = int(input("Podaj wysokość piramidy: "))

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

# Dla n=5:
# 1
# 1 2
# 1 2 3
# 1 2 3 4
# 1 2 3 4 5
Omówienie krok po kroku
  1. Zewnętrzna pętla — wiersze
    for i in range(1, n+1)i to numer wiersza (1, 2, 3...). Decyduje ile liczb w danym wierszu.
  2. Wewnętrzna pętla — kolumny
    for j in range(1, i+1) — w wierszu numer i drukujemy liczby od 1 do i. Gdy i=3, wewnętrzna pętla idzie 1, 2, 3.
  3. end=" " i print()
    end=" " zapobiega nowej linii po każdej liczbie. Pusty print() po wewnętrznej pętli przechodzi do nowego wiersza.
Zadanie 4 Wyszukiwanie liniowe z indeksem średnie

Masz listę ocen. Wczytaj ocenę do wyszukania. Wypisz wszystkie pozycje (indeksy) na których ta ocena wystąpiła. Jeśli nie ma — wypisz komunikat.

Rozwiązanie
oceny   = [4, 5, 3, 5, 2, 4, 5, 3, 4]
szukana = int(input("Której oceny szukasz? "))

pozycje = []

for i, ocena in enumerate(oceny):
    if ocena == szukana:
        pozycje.append(i)

if pozycje:
    print(f"Ocena {szukana} wystąpiła {len(pozycje)}x")
    print(f"Na pozycjach: {pozycje}")
else:
    print(f"Ocena {szukana} nie występuje na liście.")
Omówienie krok po kroku
  1. enumerate() zamiast range(len())
    for i, ocena in enumerate(oceny) daje jednocześnie indeks i wartość. To czytelniejsze niż oceny[i] przez range(len(oceny)).
  2. Zbieranie pozycji do listy
    Nie przerywamy pętli po pierwszym znalezieniu — szukamy wszystkich wystąpień. Każdy pasujący indeks trafia do pozycje.
  3. if pozycje — warunek na listę
    Pusta lista jest fałszywa (falsy). if pozycje jest prawdziwe gdy lista ma przynajmniej jeden element — nie trzeba pisać if len(pozycje) > 0.

Zadania do samodzielnego rozwiązania

Wszystkie zadania rozwiąż używając pętli for. Tam gdzie to możliwe spróbuj też wersji z list comprehension.

1★☆☆

Suma liczb parzystych

Oblicz sumę wszystkich liczb parzystych od 1 do 100. Wypisz wynik i ile takich liczb było.

Wskazówka: range(2, 101, 2) lub if x % 2 == 0
2★☆☆

Odwrócenie tekstu

Wczytaj słowo. Odwróć je literka po literce używając pętli for (bez slice [::-1]).

Wskazówka: range(len(slowo)-1, -1, -1)
3★★☆

FizzBuzz

Wypisz liczby od 1 do 50. Zamiast wielokrotności 3 wypisz "Fizz", wielokrotności 5 — "Buzz", obu — "FizzBuzz".

Wskazówka: sprawdź najpierw % 15, potem % 3 i % 5
4★★☆

Szachownica

Wypisz szachownicę 8×8 z symboli # i · (naprzemiennie). Użyj dwóch zagnieżdżonych pętli for.

Wskazówka: (i + j) % 2 == 0 decyduje o symbolu
5★★☆

List comprehension — filtr

Masz listę słów. Używając list comprehension utwórz nową listę zawierającą tylko słowa zaczynające się wielką literą, zamienione na same wielkie litery.

Wskazówka: s[0].isupper(), s.upper()
6★★★

Liczby pierwsze — Sito Eratostenesa

Zaimplementuj Sito Eratostenesa do znalezienia wszystkich liczb pierwszych do n. Użyj listy wartości True/False i zagnieżdżonych pętli.

Wskazówka: zacznij od listy [True] * (n+1), wykreślaj wielokrotności