Большинство ошибок в задачах на алгоритмы не про сами алгоритмы, а про мелочи языка и границы. Они повторяются из раза в раз, поэтому их стоит знать в лицо. Ниже семь типичных ловушек Python и способ найти ошибку, когда она уже случилась.

Список, повторённый через `*`, делит один внутренний список; генератор списков создаёт отдельные
Список, повторённый через *, делит один внутренний список; генератор списков создаёт отдельные

1. Off-by-one

Ошибка на единицу бывает в границах циклов, срезов и бинарного поиска. Запомните: range(a, b) и срез s[a:b] не включают b, а индексы идут с нуля, поэтому последний индекс равен len(a) - 1.

python
n = 5
total = 0
for i in range(1, n):          # stops at 4: n is missing
    total += i
print(total)
text
10
python
n = 5
total = 0
for i in range(1, n + 1):      # the end of range() is exclusive
    total += i
print(total)
text
15

Проверяйте границы на маленьком входе: n = 0, n = 1, n = 2.

2. Изменяемое значение по умолчанию

Значение по умолчанию создаётся один раз, при определении функции, и дальше это один и тот же список:

python
def add_item(x, items=[]):
    items.append(x)
    return items

print(add_item(1))
print(add_item(2))
print(add_item(3, []))
print(add_item.__defaults__)
text
[1]
[1, 2]
[3]
([1, 2],)