Поведение mutable-аргумента в Python
@python_quizРазберем этот квиз
Коротко: в Python значение по умолчанию для аргумента функции вычисляется один раз при определении функции. Если это изменяемый объект (например, список), то все вызовы, использующие значение по умолчанию, будут работать с одним и тем же объектом.
Условие (код)

Ожидаемый вывод и объяснение
- Первый вызов collect(1) использует список по умолчанию, который изначально пустой. В него добавляется 1 → возвращается [1].
- Второй вызов collect(2, []) явно передаёт новый пустой список, поэтому в этот отдельный список добавляется 2 → возвращается [2].
- Третий вызов collect(3) снова использует список по умолчанию. Этот объект тот же самый, что использовался в первом вызове и уже содержит [1]. В него добавляется 3 → возвращается [1, 3].
Итоговый вывод:

Анализ предложенных вариантов
- Вариант с выводом
[1]
[2]
[3]
— не учитывает тот факт, что первый и третий вызовы используют один и тот же список (нельзя получить [3] на третьем вызове, если первый добавил 1).
- Вариант с выводом
[1]
[2]
[1, 3]
— совпадает с поведением функции: список по умолчанию сохраняет изменения между вызовами, а явно переданный [] создаёт независимый список.
- Вариант с выводом
[1]
[2]
[1, 2, 3]
— предполагает, что второй вызов добавил 2 в тот же список по умолчанию, но на самом деле во втором вызове был передан отдельный список.
- Вариант с выводом
[1]
[2]
[3, 1]
— неверен по порядку элементов: при добавлении 3 в конец списка [1] получится [1, 3], а не [3, 1].
Как избежать сюрпризов (рекомендованный паттерн)
- Если нужен новый список при каждом вызове по умолчанию, используйте None и создавайте объект внутри функции:

Теперь каждый вызов без явного acc будет получать новый пустой список.
Дополнительные заметки
- Поведение относится ко всем изменяемым значениям по умолчанию (списки, словари, множества и т.д.).
- Это частая ловушка для новичков; хорошая практика — избегать изменяемых объектов как значений по умолчанию.
Вывод
- Значения по умолчанию вычисляются один раз на момент определения функции. Если они изменяемые, изменения сохраняются между вызовами, пока не будет передан явный аргумент. Используйте паттерн с None, чтобы гарантировать новый объект при каждом вызове.