Рассмотрите фрагмент на Python: def append_item(x, lst=[]): lst.append(x); return lst; — объясните, почему поведение функции может быть неожиданным при нескольких вызовах, и предложите несколько вариантов корректного решения

12 Янв в 17:00
57 +1
0
Ответы
1
Проблема — значение параметра по умолчанию вычисляется один раз при определении функции, а не при каждом вызове. Для `def append_item(x, lst=[])` это значит: один и тот же список `lst` пересоздаётся и используется при всех вызовах, поэтому элементы накапливаются.
Пример неожиданного поведения:
```
def append_item(x, lst=[]):
lst.append(x)
return lst
print(append_item(1)) # [1]
print(append_item(2)) # [1, 2] <- ожидали [2], но список тот же
print(append_item(3)) # [1, 2, 3]
```
Варианты корректного решения
1) Использовать `None` как маркер и создавать новый список внутри функции:
```
def append_item(x, lst=None):
if lst is None:
lst = []
lst.append(x)
return lst
```
2) Использовать неизменяемый тип по умолчанию и возвращать новый список:
```
def append_item(x, lst=()):
return list(lst) + [x]
```
(удобно, если не нужно менять переданный объект на месте)
3) Использовать уникальный sentinel-объект, если `None` может быть легитимным значением аргумента:
```
_sentinel = object()
def append_item(x, lst=_sentinel):
if lst is _sentinel:
lst = []
lst.append(x)
return lst
```
4) Делать копию перед модификацией (если вы хотите не менять переданный список):
```
def append_item(x, lst=None):
if lst is None:
lst = []
else:
lst = lst.copy()
lst.append(x)
return lst
```
Выберите подходящий вариант в зависимости от того, должен ли функция изменять переданный список на месте или всегда возвращать новый.
12 Янв в 17:08
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир