Ниже фрагмент Python: def foo(x=[]): x.append(1); return x; объясните неожиданное поведение при многократных вызовах foo() и предложите корректные варианты реализации

12 Фев в 12:31
25 +1
0
Ответы
1
Причина: значение аргумента по умолчанию вычисляется один раз при определении функции и затем переиспользуется. В вашем случае один и тот же список используется при всех вызовах, поэтому элементы накапливаются: первый вызов даёт [1][1][1], второй — [1,1][1,1][1,1], третий — [1,1,1][1,1,1][1,1,1].
Корректные варианты
1) Создавать список внутри при каждом вызове (обычный паттерн с None):
def foo(x=None):
if x is None:
x = []
x.append(1)
return x
2) Не мутировать переданный список — возвращать новый список:
def foo(x=None):
if x is None:
return [1]
return x + [1]
3) Если нужен неизменяемый дефолт или копирование аргумента:
def foo(x=()):
return list(x) + [1]
или
def foo(x=None):
x = [] if x is None else list(x) # копируем, чтобы не менять исходный
x.append(1)
return x
Выбирайте (1), если ожидается изменение и хранение состояния в возвращаемом списке; (2) или версия с копированием, если нежелательно менять переданный аргумент.
12 Фев в 12:36
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир