def f(a=[]):
    a.append(1)
    return a
print(f())
print(f())
Функция f(a=[]) использует изменяемый дефолтный аргумент a (список). При первом вызове, a инициализируется пустым списком, 1 добавляется в него, и список [1] возвращается.
При втором вызове, a не инициализируется заново, а сохраняет своё предыдущее значение ([1]). Поэтому, 1 добавляется к уже существующему списку, и возвращается [1, 1].
Таким образом, вывод будет:
[1]
[1, 1]Описание проблемы:
Данный код иллюстрирует распространенную ошибку, связанную с использованием изменяемых объектов (в данном случае, списка) в качестве значения аргумента по умолчанию в Python.
Объяснение работы кода:
f(a=[]) определена с аргументом a, имеющим значение по умолчанию [] (пустой список). Важно понимать, что это только один объект-список, который создается один раз при определении функции.f() (без аргументов), используется список по умолчанию []. Внутри функции к этому списку добавляется элемент 1, и список возвращается.  Таким образом, выводится [1].f() (снова без аргументов), снова используется тот же самый список, который был изменен при первом вызове.  К нему добавляется еще один элемент 1, и список возвращается. Таким образом, выводится [1, 1].Ожидаемый и фактический результат:
Наивный программист мог бы ожидать, что при каждом вызове f() будет возвращаться [1]. Однако, из-за поведения аргументов по умолчанию с изменяемыми типами, фактический результат будет:
[1]
[1, 1]Правильное решение:
Чтобы избежать этой проблемы, рекомендуется использовать None в качестве значения по умолчанию, а затем создавать список внутри функции, если аргумент не был передан:
def f(a=None):
    if a is None:
        a = []
    a.append(1)
    return a
print(f())
print(f())
В этом случае, при каждом вызове f(), будет создаваться новый пустой список, и результат будет соответствовать ожидаемому:
[1]
[1]Вывод:
При работе с аргументами по умолчанию в Python, особенно с изменяемыми типами данных, необходимо проявлять осторожность, чтобы избежать неожиданного поведения.