Wiele naraz — listy i napisy
🎯 Po co Ci to?
Dziennik ma 30 ocen, playlista 200 utworów, zdjęcie 12 milionów pikseli. Nie stworzysz 12 milionów zmiennych piksel1, piksel2… Potrzebujesz szufladki na wiele wartości naraz — z numerkami, żeby sięgać po dowolną. W Pythonie to lista; jej tekstową kuzynką jest napis. Razem z pętlą z poprzedniej jednostki tworzą duet, który obsługuje lwią część wszystkich programów świata: „przejdź po kolekcji i zrób coś z każdym elementem".
✅ Czego się nauczysz
Po tej jednostce potrafisz:
- tworzyć listy, czytać i zmieniać elementy po indeksie, dodawać nowe;
- przechodzić pętlą po liście i napisie (dwoma stylami: po elementach i po indeksach);
- wykonywać na napisach operacje: sklejanie, porównywanie, odwracanie.
📘 Wyjaśnienie
Lista. Tworzy się ją nawiasami kwadratowymi, a po elementach sięga indeksem:
oceny = [4, 5, 3, 5, 6]
print(oceny[0]) # 4 ← pierwszy element ma indeks ZERO
print(oceny[4]) # 6 ← piąty (ostatni) ma indeks 4
oceny[2] = 4 # podmiana trójki na czwórkę
oceny.append(5) # dopisanie na koniec: [4, 5, 4, 5, 6, 5]
print(len(oceny)) # 6 ← długość listy
Numerujemy od zera. Tak, to dziwne — i tak, to przemyślane: indeks mówi, „o ile elementów jesteś od początku". Pierwszy element jest przesunięty o 0. Dzięki temu range(len(lista)) daje dokładnie wszystkie indeksy, a rachunki na indeksach (np. „element środkowy to indeks len // 2") wychodzą bez poprawek o jedynkę. Konsekwencja, z którą trzeba się oswoić: ostatni element ma indeks len - 1, a sięgnięcie po oceny[6] w sześcioelementowej liście to błąd wykonania (IndexError) — komputer nie „domyśli się", że chodziło o ostatni.
Pętla po liście — dwa style. Po elementach, gdy chcesz je tylko czytać; po indeksach, gdy musisz wiedzieć „gdzie jesteś" albo coś podmieniać:
suma = 0
for ocena in oceny: # styl 1: po elementach
suma = suma + ocena
print("Średnia:", suma / len(oceny))
for i in range(len(oceny)): # styl 2: po indeksach
print("Ocena nr", i + 1, "to", oceny[i])
A teraz połącz wszystko, co umiesz — oto algorytm „największa z listy" z działu 1, wreszcie jako program:
naj = oceny[0] # kandydat: PIERWSZY element (nie zero — pamiętasz błąd z 1.2?)
for x in oceny:
if x > naj:
naj = x
print("Najlepsza ocena:", naj)
Napisy. Napis to sekwencja znaków — indeksowana jak lista: "Python"[0] to "P", len("Python") to 6, pętla for znak in slowo przechodzi po literach. Trzy operacje, które musisz znać:
- Sklejanie (konkatenacja):
"in" + "formatyka"→"informatyka";"ha" * 3→"hahaha". - Porównywanie:
==sprawdza identyczność co do znaku (wielkość liter ma znaczenie:"Ala" == "ala"toFalse);<i>porównują słownikowo — tak układa się wyrazy w słowniku, więc"ananas" < "banan"jest prawdą. - Odwracanie: pętlą, doklejając każdy znak z przodu:
slowo = input("Słowo: ")
wspak = "" # pusty napis — jak zerowanie sumy!
for znak in slowo:
wspak = znak + wspak # nowy znak z PRZODU dotychczasowego
print(wspak)
Prześledź dla „kot": "" → "k" → "ok" → "tok". Jest jedna różnica między napisem a listą, o której musisz wiedzieć: napisu nie można zmienić w miejscu (slowo[0] = "X" to błąd) — operacje na napisach zawsze budują nowy napis.
💭 Pomyśl: Mając odwracanie i porównywanie — jak jedną linijką warunku sprawdzić, czy słowo jest palindromem (czyta się tak samo wspak: „kajak", „potop")?
Sprawdź odpowiedź
if slowo == wspak: — słowo jest palindromem, gdy równa się swojemu odwróceniu. Cała trudność siedziała w odwracaniu, które już masz. W dziale 5 zrobimy z tego pełny program (z pułapkami w stylu „Kobyła ma mały bok") i dołożymy anagramy.
🐞 Znajdź błąd
Program ma wypisać co drugi element listy, zaczynając od pierwszego:
dni = ["pn", "wt", "śr", "cz", "pt", "sb", "nd"]
for i in range(1, len(dni), 2): # range z trzecim parametrem: krok
print(dni[i])
Wypisuje wt cz sb — a miało być pn śr pt nd. Znajdź przyczynę i podaj poprawkę.
Sprawdź odpowiedź
Autor pomylił „pierwszy element" z „indeksem 1". Pierwszy element listy ma indeks 0, więc powinno być range(0, len(dni), 2). Wypisane wt cz sb to elementy o indeksach 1, 3, 5 — czyli co drugi, ale od drugiego. Ta pomyłka (przesunięcie całej logiki o jeden przez złe pojmowanie indeksów) to rodzona siostra off-by-one z pętli.
⚠️ Uwaga, pułapka
W jednostce 3.1 obiecaliśmy wyjątek od zasady „b = a kopiuje". Oto on: dla list b = a nie kopiuje pudełek — obie nazwy wskazują tę samą listę. Po a = [1, 2]; b = a; b.append(3) także a ma trzy elementy! Jeśli chcesz niezależną kopię, powiedz to wprost: b = list(a). Dlaczego tak? Listy bywają milionowe — kopiowanie ich przy każdym przypisaniu rujnowałoby wydajność, więc Python kopiuje dopiero na wyraźne żądanie. Zapamiętaj zjawisko; pełne zrozumienie przyjdzie z praktyką.
🛠️ Teraz Ty
Napisz program-dziennik: wczytuje w pętli 6 ocen do listy, po czym wypisuje: średnią, najwyższą i najniższą ocenę oraz ile ocen jest poniżej średniej (uwaga: to wymaga dwóch przejść po liście — najpierw policz średnią, potem porównuj). Bez komputera: prześledź swój program dla ocen [3, 3, 6].
📐 Definicje tej lekcji
- Lista — sekwencja wartości pod jedną nazwą; elementy numerowane indeksami od 0, zmienialne,
appenddodaje. - Indeks — przesunięcie elementu względem początku; ostatni to
len - 1. - Konkatenacja — sklejanie napisów operatorem
+. - Porównanie słownikowe — porządek napisów jak w słowniku, znak po znaku.
📌 Najważniejsze w pigułce
- Lista + pętla = wzorzec obsługujący większość programów: „dla każdego elementu…".
- Indeksy od 0;
range(len(...))daje wszystkie; poza zakresem czekaIndexError. - Napisy indeksuje się jak listy, ale zmienić ich w miejscu nie można — buduje się nowe;
b = adla list NIE kopiuje.
🎒 Zadania
- Co wypisze program? Rozpisz na kartce, zanim uruchomisz.
litery = ["a", "b", "c", "d"]
wynik = ""
for i in range(len(litery)):
if i % 2 == 0:
wynik = wynik + litery[i]
print(wynik)
Wskazówka i odpowiedź
Indeksy 0–3; warunek przepuszcza parzyste: 0 i 2, czyli "a" i "c". Wynik: ac. Zadanie ćwiczy trzy rzeczy naraz: indeksowanie od zera, % z jednostki 3.2 i budowanie napisu wzorcem „pusty + doklejanie".
- Napisz program, który porównuje dwa wczytane napisy i wypisuje je „w kolejności słownikowej" (mniejszy pierwszy). Sprawdź na parach: („banan", „ananas"), („Ala", „ala"), („kot", „kotek"). Które wyniki Cię zaskoczyły i dlaczego tak jest?
Wskazówka i odpowiedź
(„ananas", „banan") — zgodnie ze słownikiem. („Ala", „ala") — "Ala" wypada pierwsze, bo wielkie litery mają w tablicy znaków (dział 2.5: ASCII!) mniejsze numery niż małe — porównywanie napisów to porównywanie numerów znaków. („kot", „kotek") — "kot" pierwsze: gdy jeden napis jest początkiem drugiego, krótszy jest „mniejszy", jak w słowniku. Reprezentacja (numery znaków) i zachowanie (porządek) łączą się tu w jedno.
- Lista
temperaturyzawiera 7 pomiarów. Napisz fragment, który buduje nową listędodatnie, zawierającą tylko wartości powyżej zera, i wypisuje obie. Dlaczego nie wolno usuwać elementów z listy w trakcie pętli po niej?
Wskazówka i odpowiedź
dodatnie = []
for t in temperatury:
if t > 0:
dodatnie.append(t)
Usuwanie z listy podczas przechodzenia po niej przesuwa indeksy pozostałych elementów — pętla zaczyna „przeskakiwać" sąsiadów usuniętych wartości i część danych ucieka bez sprawdzenia. Budowanie nowej listy jest proste, bezpieczne i szybkie — to standardowy nawyk zawodowy.
🔍 Sprawdź, czy umiesz
- Wskazać bez wahania element o indeksie 0 i element ostatni oraz zapisać ich indeksy dla listy długości $n$.
- Napisać z pamięci wzorce: suma listy, maksimum listy, odwracanie napisu.
- Wyjaśnić różnicę między
b = adla liczb i dla list.