Почему параметр функции не принимает значение по умолчанию?

Рейтинг: 0Ответов: 1Опубликовано: 13.03.2023
def f(values, arr=[]):
    for i in values:
        if i % 2 == 0:
            arr.append(i)
    return len(arr)

print(f(range(4)) + f(range(5)))

Результат выполнения этого кода равен 7. Хотя по логике должен быть равен 5. Я обнаружил, что причина этого в том, что при вызове функции "f" все разы, кроме первого, параметру "arr" не присваивается пустой список по умолчанию, как указано в коде, но передаётся не удалившийся (почему-то) список, хранившийся в этом параметре при предыдущем вызове функции "f". Почему так? Или где об этом прочитать на русском?

Ответы

▲ 0

Беда из-за использования изменяемого объекта в качестве значения параметра по умолчанию в функции. Вы пишите:

def f(values, arr=[]):

Вы создали один список arr при определении функции. При последующих вызовах arr будет сохранять свое значение между вызовами, потому что это изменяемый объект. Это означает, что если вы измените список arr внутри функции, то эти изменения будут сохранены для последующих вызовов функции.

Вы же можете создать новый объект списка внутри функции каждый раз, когда функция вызывается без указания параметра arr. Например, вот так вот:

def f(values, arr=None):
    if arr is None:
        arr = []
    for i in values:
        if i % 2 == 0:
            arr.append(i)
    return len(arr)

В этом случае будет создаваться новый пустой список arr внутри функции, только если параметр arr не был передан в явном виде. Это нам даёт гарантию, что каждый вызов функции будет использовать свой собственный список. Почитайте ещё тут