← Все вопросы

Почему функция меняет список, но не меняет число, которое я передал?

Задан 9 месяцев назад1.4к просмотров4 ответа
23

Передаю в функцию число — снаружи оно не меняется. Передаю список — меняется. Хотя код выглядит почти одинаково. Почему так?

def f(x):
    x += 1

def g(lst):
    lst.append(1)

n = 5
f(n)
print(n)    # 5, не изменилось

a = []
g(a)
print(a)    # [1], изменилось

4 ответа

38

Всё дело в изменяемости (mutable / immutable) объектов.

В функцию передаётся ссылка на объект. Но:

  • Число (int) неизменяемо. x += 1 не меняет старое число, а создаёт новое и привязывает к локальной x. Внешняя n по-прежнему ссылается на старое число — поэтому снаружи 5.
  • Список изменяемый. lst.append(1) меняет тот самый объект, на который ссылается и a снаружи. Никакого нового списка не создаётся — поэтому изменение видно везде.

Ключ: операция, которая создаёт новый объект (x += 1 для числа), не трогает оригинал, а операция, которая мутирует объект на месте (.append), трогает. Если внутри g написать lst = lst + [1], то снаружи список тоже НЕ изменится — потому что это создаёт новый список.

Егор Иванов разница между mutation и reassignment — топ объяснение · 9 месяцев назад
Николай Дмитриевич а если хочу чтобы число «изменилось» — верни его через return и присвой обратно · 9 месяцев назад
14

Число неизменяемо, список изменяемый. .append мутирует тот же объект, а += у числа создаёт новый.

0

В Python все аргументы передаются по ссылке, но:

Изменяемые объекты (списки, словари, множества) можно менять внутри функции, и изменения останутся снаружи

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

-4

Потому что список передаётся по ссылке, а число по значению.

Вероника Морозова в Python всё передаётся по ссылке (точнее — передаётся ссылка на объект). Дело не в способе передачи, а в изменяемости объекта · 9 месяцев назад

Ваш ответ

Войдите, чтобы ответить на вопрос.