Что выведет этот код?


def append_to_list(value, result=[]):
    result.append(value)
    return result

print(append_to_list(1))
print(append_to_list(2, []))
print(append_to_list(3))

Результат работы кода будет следующим:

[1]
[2]
[1, 3]

Объяснение:

  • В Python, аргументы по умолчанию вычисляются только один раз, когда функция определена. В данном случае, result=[] создается только один раз.
  • Первый вызов append_to_list(1) добавляет 1 в список result, и возвращает [1].
  • Второй вызов append_to_list(2, []) передает новый пустой список, поэтому он добавляет 2 в этот новый список и возвращает [2].
  • Третий вызов append_to_list(3) снова использует тот же самый список result, который был создан при определении функции (и который уже содержит 1), добавляет 3 к нему и возвращает [1, 3].

Эта задача демонстрирует особенность работы аргументов по умолчанию в Python, когда в качестве значения по умолчанию используется изменяемый объект (в данном случае, список).

Разберем код построчно:

  1. def append_to_list(value, result=[]):
    Определяется функция append_to_list, принимающая аргумент value и необязательный аргумент result со значением по умолчанию в виде пустого списка []. Важно: этот список создается только один раз при определении функции.
  2. result.append(value)
    Внутрь списка result добавляется значение аргумента value.
  3. return result
    Функция возвращает измененный список result.
  4. print(append_to_list(1))
    Вызывается функция append_to_list с аргументом value=1. Аргумент result не передан, поэтому используется список по умолчанию. В этот список добавляется 1, и список [1] выводится на экран.
  5. print(append_to_list(2, []))
    Вызывается функция append_to_list с аргументом value=2 и явно переданным аргументом result=[]. Внимание: здесь создается новый пустой список, в который добавляется 2. Выводится список [2]. Этот вызов никак не влияет на список, используемый по умолчанию.
  6. print(append_to_list(3))
    Вызывается функция append_to_list с аргументом value=3. Аргумент result снова не передан, поэтому используется тот же самый список по умолчанию, который был создан при первом вызове функции. В этот список (который уже содержит 1) добавляется 3. Выводится список [1, 3].

Ожидаемый результат выполнения кода:


[1]
[2]
[1, 3]
  

Важный вывод: Никогда не используйте изменяемые объекты (списки, словари, множества) в качестве значений аргументов по умолчанию. Если вам нужно такое поведение, используйте None в качестве значения по умолчанию и создавайте объект внутри функции, если аргумент равен None.

Пример правильной реализации:


def append_to_list(value, result=None):
    if result is None:
        result = []
    result.append(value)
    return result

print(append_to_list(1))
print(append_to_list(2, []))
print(append_to_list(3))
  

В этом случае результат будет:


[1]
[2]
[3]
  
0