Tworzenie, indeksowanie, metody list, list comprehension, listy zagnieżdżone.
Lista to uporządkowana, mutowalna kolekcja elementów. Może przechowywać elementy różnych typów. Jest jedną z najważniejszych struktur danych w Pythonie.
[elem1, elem2, ...][]numpy, ale na egzaminie INF.04 wystarczą listy.
# Listy różnych typów
liczby = [1, 2, 3, 4, 5]
imiona = ["Kasia", "Marek", "Zofia"]
mieszana = [1, "tekst", 3.14, True]
pusta = []
# Lista z range()
od_zera = list(range(10))
print(od_zera) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Lista przez powielenie
zera = [0] * 5
print(zera) # [0, 0, 0, 0, 0]
# Lista z tekstu
litery = list("Python")
print(litery) # ['P', 'y', 't', 'h', 'o', 'n']
# Zagnieżdżona — macierz 3x3
macierz = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
print(macierz[1][2]) # 6
Elementy listy są numerowane od 0. Można też używać indeksów ujemnych — liczonych od końca.
| Zapis | Znaczenie |
|---|---|
lista[0] | pierwszy element |
lista[-1] | ostatni element |
lista[-2] | przedostatni element |
lista[2:5] | elementy od indeksu 2 do 4 |
lista[:3] | pierwsze 3 elementy |
lista[2:] | od indeksu 2 do końca |
lista[::2] | co drugi element |
lista[::-1] | odwrócona lista |
IndexError. Dla listy 5-elementowej poprawne indeksy to 0–4 (lub -5 do -1).
oceny = [3, 4, 5, 2, 4, 5, 3]
# 0 1 2 3 4 5 6
# -7 -6 -5 -4 -3 -2 -1
print(oceny[0]) # 3 — pierwszy
print(oceny[-1]) # 3 — ostatni
print(oceny[2]) # 5 — trzeci
print(oceny[-2]) # 5 — przedostatni
# Wycinki
print(oceny[1:4]) # [4, 5, 2]
print(oceny[:3]) # [3, 4, 5]
print(oceny[4:]) # [4, 5, 3]
print(oceny[::2]) # [3, 5, 4, 3] — co drugi
print(oceny[::-1]) # [3, 5, 4, 2, 5, 4, 3] — odwrócona
# Zmiana elementu przez indeks
oceny[3] = 6
print(oceny) # [3, 4, 5, 6, 4, 5, 3]
| Metoda | Działanie | Zwraca |
|---|---|---|
append(x) | dodaje x na koniec | None |
insert(i, x) | wstawia x na pozycję i | None |
extend(lista) | dodaje wszystkie elementy listy | None |
remove(x) | usuwa pierwsze wystąpienie x | None |
pop() | usuwa i zwraca ostatni element | element |
pop(i) | usuwa i zwraca element z indeksu i | element |
index(x) | indeks pierwszego wystąpienia x | int |
count(x) | ile razy x występuje na liście | int |
sort() | sortuje listę w miejscu | None |
reverse() | odwraca listę w miejscu | None |
clear() | usuwa wszystkie elementy | None |
copy() | zwraca płytką kopię listy | lista |
lista.sort() — modyfikuje oryginał, zwraca None.sorted(lista) — zwraca nową listę, oryginał bez zmian.reverse=True i key=funkcja.
lista = [3, 1, 4, 1, 5]
# Dodawanie
lista.append(9)
print(lista) # [3, 1, 4, 1, 5, 9]
lista.insert(2, 99)
print(lista) # [3, 1, 99, 4, 1, 5, 9]
lista.extend([10, 11])
print(lista) # [3, 1, 99, 4, 1, 5, 9, 10, 11]
# Usuwanie
lista.remove(99) # usuwa pierwsze 99
print(lista) # [3, 1, 4, 1, 5, 9, 10, 11]
ostatni = lista.pop()
print(ostatni) # 11
print(lista) # [3, 1, 4, 1, 5, 9, 10]
# Informacje
print(lista.index(4)) # 2 — pozycja czwórki
print(lista.count(1)) # 2 — ile jedynek
# Sortowanie
lista.sort()
print(lista) # [1, 1, 3, 4, 5, 9, 10]
lista.sort(reverse=True)
print(lista) # [10, 9, 5, 4, 3, 1, 1]
| Operacja | Znaczenie | Przykład |
|---|---|---|
len(lista) | długość listy | len([1,2,3]) → 3 |
x in lista | czy x jest na liście | 5 in [1,5,3] → True |
x not in lista | czy x nie jest na liście | 7 not in [1,5,3] → True |
lista1 + lista2 | łączenie list | [1,2]+[3,4] → [1,2,3,4] |
lista * n | powielenie listy | [0]*3 → [0,0,0] |
del lista[i] | usuwa element o indeksie i | del lista[2] |
del lista[a:b] | usuwa wycinek | del lista[1:3] |
b = a — to nie jest kopia! Obie zmienne wskazują na tę samą listę. Żeby skopiować: b = a.copy(), b = a[:] lub b = list(a).
a = [1, 2, 3, 4, 5]
# Sprawdzanie przynależności
print(3 in a) # True
print(9 in a) # False
print(9 not in a) # True
# Łączenie i powielanie
b = [6, 7, 8]
c = a + b
print(c) # [1, 2, 3, 4, 5, 6, 7, 8]
print([0] * 4) # [0, 0, 0, 0]
# Usuwanie przez del
d = [10, 20, 30, 40, 50]
del d[2]
print(d) # [10, 20, 40, 50]
del d[1:3]
print(d) # [10, 50]
# Pułapka z kopiowaniem
oryg = [1, 2, 3]
alias = oryg # to samo miejsce w pamięci!
alias.append(99)
print(oryg) # [1, 2, 3, 99] — zmienione!
kopia = oryg.copy() # prawdziwa kopia
kopia.append(0)
print(oryg) # [1, 2, 3, 99] — bez zmian
List comprehension to elegancki sposób tworzenia list. Omawialiśmy podstawy w kafelku 04 — tutaj rozszerzamy o bardziej złożone przypadki.
[x for x in lista if warunek][f(x) for x in lista if warunek][x for wiersz in macierz for x in wiersz][a if warunek else b for x in lista][x for wiersz in macierz for x in wiersz] — kolejność pętli taka sama jak przy zagnieżdżeniu: najpierw zewnętrzna (wiersz), potem wewnętrzna (x).
# Filtrowanie z transformacją
liczby = range(1, 21)
nieparzyste_kwadraty = [x**2 for x in liczby if x % 2 != 0]
print(nieparzyste_kwadraty)
# [1, 9, 25, 49, 81, 121, 169, 225, 289, 361]
# if-else wewnątrz
wyniki = [x if x >= 0 else 0 for x in [-3, 5, -1, 8, -2]]
print(wyniki) # [0, 5, 0, 8, 0]
# Spłaszczenie macierzy
macierz = [[1,2,3],[4,5,6],[7,8,9]]
plaska = [x for wiersz in macierz for x in wiersz]
print(plaska) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Pary (x, y) gdzie x != y
pary = [(x, y) for x in range(1,4)
for y in range(1,4)
if x != y]
print(pary)
# [(1,2),(1,3),(2,1),(2,3),(3,1),(3,2)]
Lista list to odpowiednik tablicy dwuwymiarowej. Każdy wiersz to osobna lista.
macierz[wiersz][kolumna][[0]*3]*3 tworzy 3 referencje do tej samej listy![[0 for _ in range(m)] for _ in range(n)] — tworzy n wierszy, każdy to osobna lista m zer. Metoda [[0]*m]*n jest niebezpieczna — wszystkie wiersze to ten sam obiekt.
# Macierz 3x3
m = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
print(m[0]) # [1, 2, 3] — pierwszy wiersz
print(m[1][2]) # 6 — wiersz 1, kolumna 2
# Iterowanie
for wiersz in m:
for elem in wiersz:
print(elem, end=" ")
print()
# Bezpieczna pusta macierz 4x3
pusta = [[0 for _ in range(3)] for _ in range(4)]
pusta[1][2] = 9
print(pusta)
# [[0,0,0],[0,0,9],[0,0,0],[0,0,0]]
# Suma wszystkich elementów
suma = sum(m[i][j] for i in range(3) for j in range(3))
print(suma) # 45
# Transponowanie macierzy
t = [[m[j][i] for j in range(3)] for i in range(3)]
print(t) # [[1,4,7],[2,5,8],[3,6,9]]
Masz listę z powtarzającymi się elementami. Utwórz nową listę bez duplikatów, zachowując kolejność pierwszych wystąpień. Wypisz obie listy i liczbę usuniętych duplikatów.
lista = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
bez_duplikatow = []
for elem in lista:
if elem not in bez_duplikatow:
bez_duplikatow.append(elem)
usunieto = len(lista) - len(bez_duplikatow)
print(f"Oryginalna: {lista}")
print(f"Bez duplikatów: {bez_duplikatow}")
print(f"Usunięto: {usunieto} duplikatów")
bez_duplikatow. Będziemy do niej dodawać tylko te elementy, których jeszcze nie ma.
if elem not in bez_duplikatow sprawdza czy element już trafił do nowej listy. Jeśli nie — dodajemy go. Jeśli tak — pomijamy.
Wczytaj od użytkownika n ocen (liczba n też jest wczytywana). Oblicz i wypisz: średnią, medianę, modę (najczęstszą ocenę), liczbę ocen powyżej średniej.
n = int(input("Ile ocen? "))
oceny = []
for i in range(n):
o = int(input(f"Ocena {i+1}: "))
oceny.append(o)
# Średnia
srednia = sum(oceny) / len(oceny)
# Mediana
posortowane = sorted(oceny)
srodek = len(posortowane) // 2
if len(posortowane) % 2 == 0:
mediana = (posortowane[srodek-1] + posortowane[srodek]) / 2
else:
mediana = posortowane[srodek]
# Moda — najczęstsza ocena
moda = max(set(oceny), key=oceny.count)
# Powyżej średniej
pow_sredniej = len([o for o in oceny if o > srednia])
print(f"Średnia: {srednia:.2f}")
print(f"Mediana: {mediana}")
print(f"Moda: {moda}")
print(f"Powyżej średniej: {pow_sredniej}")
srodek = n // 2 daje indeks.
set(oceny) daje unikalne wartości. max(..., key=oceny.count) wybiera tę, która najczęściej pojawia się na liście. Eleganckie jednoliniowe rozwiązanie.
[o for o in oceny if o > srednia] tworzy listę ocen powyżej średniej. len() zlicza ile ich jest. Można też użyć pętli z licznikiem.
Napisz funkcję rotuj(lista, k) która przesuwa elementy listy o k pozycji w prawo. Np. dla [1,2,3,4,5] i k=2 wynik to [4,5,1,2,3]. Rozwiąż to bez tworzenia nowej listy (w miejscu) używając wycinków.
def rotuj(lista, k):
n = len(lista)
k = k % n # obsługa k > n
lista[:] = lista[-k:] + lista[:-k]
# Test
a = [1, 2, 3, 4, 5]
rotuj(a, 2)
print(a) # [4, 5, 1, 2, 3]
b = [1, 2, 3, 4, 5]
rotuj(b, 7) # 7 % 5 = 2, to samo co k=2
print(b) # [4, 5, 1, 2, 3]
c = ["a", "b", "c", "d"]
rotuj(c, 1)
print(c) # ['d', 'a', 'b', 'c']
lista[-2:] dla k=2 daje [4, 5] — te trafią na początek po rotacji.
lista[:-2] daje [1, 2, 3] — te trafią na koniec.
lista[:] = nowa_wartość zastępuje zawartość tej samej listy. Gdybyśmy napisali lista = ... — stworzylibyśmy nową zmienną lokalną, oryginał by się nie zmienił.
Korzystaj z metod list, list comprehension i operacji na wycinkach. Nie używaj gotowych funkcji tam gdzie zadanie prosi o samodzielną implementację.
Odwrócenie listy
Odwróć listę bez użycia reverse() ani [::-1] — napisz własną funkcję używając pętli i zamiany elementów miejscami.
lista[i] z lista[n-1-i], iteruj do połowyFiltrowanie listy
Masz listę liczb. Używając list comprehension utwórz trzy nowe listy: liczby ujemne, zero i dodatnie. Wypisz każdą z nich.
ifSortowanie bąbelkowe
Zaimplementuj sortowanie bąbelkowe na liście liczb — dwie zagnieżdżone pętle, zamiana sąsiednich elementów. Nie używaj sort() ani sorted().
lista[j] > lista[j+1] — zamień je miejscamiWspólne elementy
Masz dwie listy liczb. Znajdź ich część wspólną (elementy obecne w obu) bez duplikatów. Nie używaj zbiorów — użyj list i pętli.
if elem in lista2 and elem not in wynikMacierz — suma wierszy i kolumn
Dla macierzy 4×4 (wpisanej ręcznie w kod) oblicz i wypisz sumę każdego wiersza i każdej kolumny oraz sumę przekątnej głównej.
sum(macierz[i]) dla wiersza, macierz[i][j] dla kolumnyScalanie posortowanych list
Masz dwie posortowane listy. Scal je w jedną posortowaną listę bez użycia sort() — porównuj elementy z obu list i buduj wynik element po elemencie.
a[i] z b[j], mniejszy dodaj do wyniku