🐛 Типичные ошибки

⚡ Топ ошибок

  • Off-by-one: обращение к индексу len(my_list) вместо len(my_list) - 1.
  • Изменение списка во время итерации по нему.
  • Путаница in: поиск целого элемента vs подстроки.
  • Shallow copy: копирование вложенных списков через [:] не копирует внутренние списки.
  • Повторение списка с изменяемыми элементами: [[0]] * 3 создаёт 3 ссылки на один внутренний список.
  • Сравнение списков с несовместимыми типами элементов.

❌ Ошибка 1: Off-by-one при индексации

# Wrong: IndexError
my_list = [10, 20, 30]
print(my_list[len(my_list)])  # IndexError: list index out of range

Сообщение об ошибке: IndexError: list index out of range

Почему возникает: последний допустимый индекс равен len(my_list) - 1, а не len(my_list).

✅ Исправление

my_list = [10, 20, 30]
print(my_list[len(my_list) - 1])  # 30
# or
print(my_list[-1])  # 30

❌ Ошибка 2: Изменение списка во время итерации

# Wrong: skipped elements / unexpected behavior
numbers = [1, 2, 3, 4]
for num in numbers:
    if num % 2 == 0:
        numbers.remove(num)
print(numbers)  # [1, 3] — иногда кажется, что работает

Почему возникает: при удалении элемента сдвигаются индексы, и цикл может пропустить элементы или выйти за границы.

✅ Исправление

numbers = [1, 2, 3, 4]
numbers = [num for num in numbers if num % 2 != 0]
print(numbers)  # [1, 3]

# or iterate over a copy
numbers = [1, 2, 3, 4]
for num in numbers[:]:  # iterate over a copy
    if num % 2 == 0:
        numbers.remove(num)
print(numbers)  # [1, 3]

❌ Ошибка 3: Путаница in с подстрокой

# Wrong: expects substring match
fruits = ["apple", "banana", "cherry"]
print("app" in fruits)  # False

Почему возникает: оператор in для списка проверяет полное совпадение элемента, а не вхождение подстроки. Для подстроки нужно перебирать элементы и использовать in для строк.

✅ Исправление

fruits = ["apple", "banana", "cherry"]
matches = [fruit for fruit in fruits if "app" in fruit]
print(matches)  # ['apple']

❌ Ошибка 4: Проблемы с поверхностным копированием

# Wrong: nested list is shared
matrix = [[0] * 3] * 3
matrix[0][0] = 1
print(matrix)
# [[1, 0, 0], [1, 0, 0], [1, 0, 0]]

Почему возникает: оператор * копирует ссылки на один и тот же внутренний список. Изменение одной строки меняет все.

✅ Исправление

matrix = [[0 for _ in range(3)] for _ in range(3)]
matrix[0][0] = 1
print(matrix)
# [[1, 0, 0], [0, 0, 0], [0, 0, 0]]

❌ Ошибка 5: Повторение списка с изменяемыми элементами

# Wrong: shared mutable items
buckets = [[]] * 3
buckets[0].append(1)
print(buckets)  # [[1], [1], [1]]

Почему возникает: [[]] * 3 создаёт 3 ссылки на один пустой список. append() виден через все ссылки.

✅ Исправление

buckets = [[] for _ in range(3)]
buckets[0].append(1)
print(buckets)  # [[1], [], []]

❌ Ошибка 6: Сравнение несовместимых типов

# Wrong: TypeError
list1 = [1, 2, "apple"]
list2 = [1, 2, 3]
print(list1 < list2)
# TypeError: '<' not supported between instances of 'str' and 'int'

Сообщение об ошибке: TypeError: '<' not supported between instances of 'str' and 'int'

Почему возникает: Python не сравнивает напрямую строки и числа. Списки должны содержать сравнимые элементы.

✅ Исправление

list1 = [1, 2, 3]
list2 = [1, 2, 3]
print(list1 == list2)  # True

# Convert to a common type if needed
list1 = [1, 2, "3"]
list2 = [1, 2, 3]
print([str(x) for x in list1] == [str(x) for x in list2])  # True

❌ Ошибка 7: Попытка изменить переменную цикла вместо списка

# Wrong: list is unchanged
numbers = [1, 2, 3]
for num in numbers:
    num = num * 2
print(numbers)  # [1, 2, 3]

Почему возникает: переменная цикла num — это локальная переменная, которая получает копию ссылки на элемент. Её переопределение не меняет список.

✅ Исправление

numbers = [1, 2, 3]
for i in range(len(numbers)):
    numbers[i] = numbers[i] * 2
print(numbers)  # [2, 4, 6]

# or modern
numbers = [num * 2 for num in numbers]
print(numbers)  # [2, 4, 6]