Объяснить как работает изменяемый аргумент по умолчанию в функции

24. Объяснить как работает изменяемый аргумент по умолчанию в функции

Условие задачи Нужно сказать результат выполнения кода ниже и объяснить как он работает

def extendList(val, list=[]):
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123, [])
list3 = extendList('a')

print(f"{list1 = }")
print(f"{list2 = }")
print(f"{list3 = }")
Спойлеры к решению
Подсказки
  • В Python значения аргументов по умолчанию создаются один раз в момент объявления функции.
  • list=[] — изменяемый объект.
  • Поэтому один и тот же список будет переиспользоваться между вызовами функции.
  • list1 и list3 используют общий список по умолчанию.
  • list2 получает отдельный список, потому что он передан явно: [].
  • Также не стоит называть параметр list, потому что так перекрывается встроенный тип list.
Решение
def extendList(val, list=[]):
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123, [])
list3 = extendList('a')

print(f"{list1 = }")
print(f"{list2 = }")
print(f"{list3 = }")

Результат:

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']

Разбор:

list1 = extendList(10)

Функция вызывается без второго аргумента, поэтому используется список по умолчанию. В него добавляется 10:

[10]

Дальше:

list2 = extendList(123, [])

Здесь передан новый отдельный список []. В него добавляется 123:

[123]

Дальше:

list3 = extendList('a')

Функция снова вызывается без второго аргумента, поэтому используется тот же самый список по умолчанию, который уже содержит 10. В него добавляется 'a':

[10, 'a']

Так как list1 и list3 ссылаются на один и тот же список, при выводе они будут одинаковыми:

list1 is list3  # True

Правильная реализация:

def extend_list(val, items=None):
    if items is None:
        items = []

    items.append(val)
    return items

В таком варианте новый список создаётся внутри функции при каждом вызове без второго аргумента.