Cel: po tym rozdziale Twój kod będzie krótszy, szybszy i bardziej „pythonowy”.
Poznasz:
- comprehensions (czyli skrócony zapis pętli),
- iteratory i generatory,
- funkcje map, filter, reduce,
- lambda (funkcje anonimowe),
- dekoratory (modyfikowanie funkcji w locie).
1) Comprehensions – pętle w jednej linijce
To prosty zapis, który tworzy listy, słowniki i zbiory bez długich pętli.
Lista
# zwykła pętla
squares = []
for n in range(10):
squares.append(n * n)
# krócej:
squares = [n * n for n in range(10)]
Z warunkiem:
even = [n for n in range(10) if n % 2 == 0]
print(even) # [0, 2, 4, 6, 8]
Słownik
names = ["Ala", "Ola", "Ela"]
lengths = {n: len(n) for n in names}
print(lengths) # {'Ala': 3, 'Ola': 3, 'Ela': 3}
Zbiór
unique = {c.lower() for c in "PythonPYTHON"}
print(unique) # {'p', 'y', 't', 'h', 'o', 'n'}
💡 Używaj comprehensions, gdy tworzysz nową kolekcję z innej.
Jeśli logika jest zbyt skomplikowana – lepsza zwykła pętla.
2) Iteratory – obiekty „po których się chodzi”
Iterator to „pilot” do przechodzenia po danych.
Każdy iterator ma metody __iter__() i __next__().
nums = [1, 2, 3]
it = iter(nums)
print(next(it)) # 1
print(next(it)) # 2
Pętla
forsama w tle korzysta z iteratorów.
3) Generatory – dane „na żądanie”
Generator to specjalny iterator, który nie trzyma wszystkiego w pamięci, tylko daje kolejne elementy w miarę potrzeby.
def licz_od_do(a, b):
while a <= b:
yield a
a += 1
for n in licz_od_do(3, 6):
print(n) # 3, 4, 5, 6
Można też zrobić generator w jednej linijce:
suma = sum(n * n for n in range(1_000_000))
print(suma)
4) Funkcje wyższego rzędu – map, filter, reduce
map – przekształca każdy element:
nums = [1, 2, 3]
doubled = list(map(lambda x: x * 2, nums))
print(doubled) # [2, 4, 6]
filter – zostawia elementy spełniające warunek:
even = list(filter(lambda x: x % 2 == 0, nums))
print(even) # [2]
reduce – redukuje całą listę do jednej wartości (trzeba functools):
from functools import reduce
product = reduce(lambda a, b: a * b, nums)
print(product) # 6
5) Funkcje anonimowe – lambda
lambda to krótka funkcja w jednej linijce.
kwadrat = lambda x: x**2
print(kwadrat(5)) # 25
Praktyczne użycie:
names = ["ela", "ola", "Ala"]
print(sorted(names, key=lambda n: n.lower()))
# ['Ala', 'ela', 'ola']
6) Dekoratory – funkcje, które ulepszają inne funkcje
Dekorator przyjmuje funkcję, a zwraca nową, np. z dodatkowymi logami.
def log(func):
def wrapper(*args, **kwargs):
print("Wywołuję:", func.__name__)
result = func(*args, **kwargs)
print("Wynik:", result)
return result
return wrapper
@log
def add(a, b):
return a + b
add(3, 4)
Przydatne np. do mierzenia czasu działania, logowania, sprawdzania uprawnień.
7) Mini-projekty (spróbuj sam)
A) Generator haseł – comprehension + random
import random, string
password = "".join(random.choice(string.ascii_letters) for _ in range(12))
print(password)
B) Analiza tekstu – dict comprehension
txt = "Ala ma kota a kot ma Ale"
counts = {w: txt.split().count(w) for w in set(txt.split())}
print(counts)
C) Pomiar czasu działania – dekorator
import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"Czas: {end - start:.5f}s")
return result
return wrapper
@timer
def slow():
time.sleep(1)
return "gotowe"
print(slow())
8) Typowe pułapki i jak ich uniknąć
| Problem | Co się dzieje | Rada |
|---|---|---|
| Zbyt skomplikowany comprehension | kod trudny do czytania | podziel na kilka prostych pętli |
Nadużywanie lambda | trudniej debugować | dla większej logiki zrób normalną funkcję |
| Generator użyty drugi raz | daje puste wyniki | twórz nowy generator przy każdym użyciu |
Brak functools.wraps w dekoratorze | tracisz nazwę i opis funkcji | użyj from functools import wraps i dodaj @wraps(func) |
9) Zadania do samodzielnego zrobienia
- Zbuduj list comprehension, który zwróci kwadraty liczb parzystych od 0 do 20.
- Napisz generator liczb Fibonacciego.
- Użyj map i filter, aby z listy słów wybrać te na „a” i zamienić na wielkie litery.
- Stwórz dekorator, który mierzy czas działania dowolnej funkcji i wypisuje wynik.
- Użyj reduce, aby obliczyć największy wspólny dzielnik (NWD) listy liczb.
Co zabierasz z odcinka 10?
- Tworzysz list/dict/set comprehensions.
- Wiesz, jak działają iteratory i generatory.
- Używasz map, filter, reduce i lambda.
- Potrafisz pisać dekoratory do logowania czy pomiaru czasu.
- Twój kod staje się krótszy, szybszy i czytelniejszy.

