Глава 11 · Очень много информации!

Отладка коллекций: 14 типичных ошибок

IndexError, KeyError, путаница append/extend, aliasing, поверхностная копия и другие ловушки — в одном месте, с примерами и разбором.

14 типичных ошибок при работе со списками, кортежами, множествами и словарями — каждая с примером и объяснением. Первые две разберём отдельно с диаграммой, остальные — компактно.

IndexError — визуально

A0-3B1-2C2-1
items = ['A', 'B', 'C'] — допустимые индексы только 0, 1, 2 (и -1, -2, -3)
indexerror.py
items = ['A', 'B', 'C']
print(items[3])
# IndexError: list index out of range

KeyError — визуально

'name''Anna'
У student есть только ключ 'name' — обращение по ключу 'email' не находит ничего и вызывает KeyError
keyerror.py
student = {'name': 'Anna'}
print(student['email'])
# KeyError: 'email'

Ещё 12 типичных ошибок

1 · IndexError
bug.py
items = ['A', 'B', 'C']
print(items[3])

Допустимые индексы — от 0 до len(items)-1 = 2. Индекс 3 не существует.

2 · KeyError
bug.py
student = {'name': 'Anna'}
print(student['email'])

Такого ключа в словаре нет. Безопаснее: student.get('email').

3 · ValueError от index()/remove()
bug.py
fruits = ['яблоко', 'банан']
fruits.remove('вишня')

'вишня' нет в списке — remove() ищет по значению и не находит его. Проверьте через in перед вызовом.

4 · TypeError: unhashable type
bug.py
bad = {[1, 2]: 'значение'}

Список нельзя использовать как ключ словаря (или элемент множества) — он изменяем, а значит не хешируем (§11.16).

5 · append() вместо extend()
bug.py
a = [1, 2]
a.append([3, 4])
print(a)   # [1, 2, [3, 4]], а не [1, 2, 3, 4]

append() всегда добавляет один объект. Чтобы добавить элементы ИЗ списка — нужен extend().

6 · x = x.sort() — потеря списка
bug.py
numbers = [3, 1, 2]
numbers = numbers.sort()
print(numbers)   # None

sort() мутирует список на месте и возвращает None. Присваивание результата обратно стирает список.

7 · Aliasing вместо копии
bug.py
a = [1, 2, 3]
b = a
b.append(4)
print(a)   # тоже [1, 2, 3, 4]!

b = a не копирует список — оба имени указывают на один и тот же объект (§11.9). Нужно b = a.copy().

8 · Поверхностная копия и вложенный список
bug.py
original = [[1, 2]]
copy_ = original.copy()
copy_[0][0] = 99
print(original)   # [[99, 2]] — тоже изменился!

.copy() копирует только внешний список — вложенные списки остаются общими (§11.10). Нужен copy.deepcopy().

9 · [[0]*3]*3 — общая строка
bug.py
grid = [[0] * 3] * 3
grid[0][0] = 1
print(grid)   # изменились ВСЕ строки

*3 копирует ссылку на один и тот же внутренний список трижды. Используйте [[0]*3 for _ in range(3)].

10 · Изменение списка во время перебора
bug.py
items = [1, 2, 3, 4]
for x in items:
    if x % 2 == 0:
        items.remove(x)
print(items)   # не то, что ожидали

Удаление элемента сдвигает индексы прямо во время перебора — часть значений пропускается. Стройте новый список или перебирайте копию.

11 · {} вместо set()
bug.py
empty = {}
print(type(empty))   # <class 'dict'>, а не set!

Пустой словарь и пустое множество выглядят по-разному только в непустом виде. Пустое множество — всегда set().

12 · Кортеж из одного элемента без запятой
bug.py
point = (42)
print(type(point))   # <class 'int'>

Кортеж создаёт запятая, а не скобки. Нужно (42,).

13 · in у словаря проверяет ключи, не значения
bug.py
student = {'name': 'Anna'}
print('Anna' in student)   # False!

'Anna' — значение, а не ключ. Для проверки значений: 'Anna' in student.values().

14 · Перепутан порядок вложенного индекса
bug.py
matrix = [[1, 2, 3], [4, 5, 6]]
print(matrix[2][0])   # IndexError

У matrix всего 2 строки (индексы 0 и 1) по 3 столбца — сначала строка, потом столбец, не наоборот.

Метод отладки: трасса по шагам

  • Перед запуском предскажите, что будет в переменной — потом сравните с реальным выводом.
  • Для ошибок с индексами/ключами явно выпишите допустимый диапазон или список ключей.
  • Если результат «странный, но без ошибки» — подозревайте aliasing или поверхностную копию.
  • print() после каждого шага — самый надёжный способ найти момент, где ожидание разошлось с реальностью.
Практика: находим и исправляем ошибки в коллекциях
Интерактивный ноутбук прямо в браузере — Python 3.14 через Pyodide, без установки
Открыть практику →