Вопрос #1614922

Объясните поведение Python-кода с изменяемым аргументом по умолчанию: def add(x, lst=[]): lst.append(x); return lst; — почему это поведение встречается и как его исправить

Ответы
1


Коротко: параметр по умолчанию вычисляется один раз — при определении функции. Если это изменяемый объект (например, список), то все вызовы без явного аргумента будут использовать один и тот же объект, поэтому элементы накапливаются.
Пример поведения:
```
def add(x, lst=[]):
lst.append(x)
return lst
print(add(1)) # -> [1]
print(add(2)) # -> [1, 2] # не [2], потому что тот же lst
print(add(3, [])) # -> [3] # передали новый список явно
print(add(4)) # -> [1, 2, 4]
```
Почему так происходит: значение выражения после `=` (здесь `[]`) вычисляется один раз при загрузке/компиляции модуля и привязывается как объект по умолчанию к функции. При последующих вызовах этот же объект переиспользуется.
Как исправить:
- Использовать значение по умолчанию `None` и создавать новый список внутри функции:
```
def add(x, lst=None):
if lst is None:
lst = []
lst.append(x)
return lst
```
Теперь
```
print(add(1)) # -> [1]
print(add(2)) # -> [2]
```
Альтернативы: использовать незаменимый синглтон-сентинел вместо `None`, возвращать новый список через `lst + [x]` (создаёт копию), или явно передавать новый список при каждом вызове. Если вы хотите именно разделяемое поведение — оставьте текущую реализацию.

Минимум 10 символов
Прямой эфир