Как работает изменяемый параметр функции по умолчанию

При обычном запуске все три assert проходят. Каждый вызов меняет один общий default-список; во втором сравнении обе стороны ссылаются на него же, хотя вызовы последовательно добавляют элементы.

Короткий ответ

Что ответить на собеседовании

При обычном запуске все три assert проходят. Каждый вызов меняет один общий default-список; во втором сравнении обе стороны ссылаются на него же, хотя вызовы последовательно добавляют элементы.

Подробный разбор

Ответ с пояснениями

Условие

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

def add_one(lst=[]):
    lst.append(1)
    return lst

assert add_one() == [1]
assert add_one() == add_one()
assert add_one() == [1, 1, 1, 1]

Ответ

При обычном запуске все три assert проходят. Каждый вызов меняет один общий default-список; во втором сравнении обе стороны ссылаются на него же, хотя вызовы последовательно добавляют элементы.

После первого вызова список равен [1]. Во втором assert левый вызов делает [1, 1], правый — [1, 1, 1]. Левая сторона хранит не снимок, а ссылку на тот же объект, поэтому сравниваются одинаковые актуальные списки.

Последний вызов добавляет четвёртую единицу, и сравнение с [1, 1, 1, 1] тоже истинно. При Python -O assert удаляются вместе с находящимися внутри вызовами. Для независимых результатов используйте lst=None с созданием нового списка внутри функции.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее