Debugowanie kolekcji: 14 typowych błędów
IndexError, KeyError, append/extend zamieszania, aliasing, powierzchowne teksty i inne pułapki są w jednym miejscu, z przykładami i analizą.
14 typowych błędów przy pracy z listami, krotkami, zbiorami i słownikami — każdy z Przykład i wyjaśnienie. Pierwsze dwa będą analizowane osobno za pomocą diagramu, reszta będzie zwarta.
IndexError — wizualnie
items = ['A', 'B', 'C']
print(items[3])
# IndexError: list index out of range
KeyError — wizualnie
student = {'name': 'Anna'}
print(student['email'])
# KeyError: 'email'
12 kolejnych powszechnych błędów
items = ['A', 'B', 'C']
print(items[3])
Prawidłowe indeksy mieszczą się między 0 a len(items)-1 = 2. Indeks 3 nie istnieje.
student = {'name': 'Anna'}
print(student['email'])
W słowniku nie ma takiego klucza. Safer: student.get('email').
fruits = ['jabłko', 'banan']
fruits.remove('wiśnia')
„wiśnia”
bad = {[1, 2]: „znaczenie”}
Lista nie może być używana jako klucz słownikowy (ani element zbioru) — jest modyfikowalna, co oznacza, że nie jest haszalna (§11.16).
a = [1, 2]
a.append([3, 4])
print(a) # [1, 2, [3, 4]] zamiast [1, 2, 3, 4]
append() zawsze dodaje jeden obiekt. Aby dodać elementy Z listy, musisz extend().
numbers = [3, 1, 2]
numbers = numbers.sort()
print(numbers) # None
sort() mutuje lista na miejscu i zwraca None. Przypisanie wyniku z powrotem usuwa lista.
a = [1, 2, 3]
b = a
b.append(4)
print(a) # też [1, 2, 3, 4]!
b = a nie kopiuje lista — oba nazwy wskazują na ten sam obiekt (§11.9). Należy b = a.copy().
original = [[1, 2]]
copy_ = original.copy()
copy_[0][0] = 99
print(original) # [[99, 2]] — również się zmieniło!
. copy() kopiuje tylko zewnętrzną lista—listy zagnieżdżone pozostają współdzielone (§11.10). Potrzeba copy.deepcopy().
grid = [[0] * 3] * 3
grid[0][0] = 1
print(grid) # WSZYSTKIE linie się zmieniły
*3 kopiuje odnośnik do tego samego wewnętrznego lista trzy razy. Użyj [[0]*3 for _ in range(3)].
items = [1, 2, 3, 4]
for x in items:
if x % 2 == 0:
items.remove(x)
print(items) # nie to, czego oczekiwano
Usunięcie elementu przesuwa indeksy w trakcie iteracji — część wartości zostaje pominięta. Twórz nowy lista lub iteruj po kopii.
empty = {}
print(type(empty)) #<class 'dict'>, nie set!
Pusty słownik i pusty zbiór wyglądają inaczej tylko w stanie niepustym. Pusty zbiór — zawsze set().
point = (42)
print(type(point)) # <class 'int'>
Krotka powstaje przez przecinek, a nie przez nawiasy. Jest to konieczne (42,).
student = {'name': 'Anna'}
print('Anna' in student) # False!
'Anna' to wartość, a nie klucz. Aby sprawdzić wartości: 'Anna' in student.values().
matrix = [[1, 2, 3], [4, 5, 6]]
print(matrix[2][0]) # IndexError
matrix mają tylko 2 wiersze (indeksy 0 i 1) po 3 kolumny – najpierw łańcuch znaków, potem kolumnę, a nie odwrotnie.
Metoda debugowania: Śledzenie krok po kroku
- Przed uruchomieniem przewidź, co będzie w zmiennej — potem porównaj z rzeczywistym wynikiem.
- W przypadku błędów indeksu/klucza wyraźnie określ ważny zakres lub lista kluczy.
- Jeśli wynik to „dziwny, ale bez błędów”
- print() po każdym kroku to najbardziej wiarygodny sposób, by znaleźć moment, w którym oczekiwania odbiegły od rzeczywistości.