Почему функция меняет список, но не меняет число, которое я передал?
Передаю в функцию число — снаружи оно не меняется. Передаю список — меняется. Хотя код выглядит почти одинаково. Почему так?
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 ответа
Всё дело в изменяемости (mutable / immutable) объектов.
В функцию передаётся ссылка на объект. Но:
- Число (
int) неизменяемо.x += 1не меняет старое число, а создаёт новое и привязывает к локальнойx. Внешняяnпо-прежнему ссылается на старое число — поэтому снаружи 5. - Список изменяемый.
lst.append(1)меняет тот самый объект, на который ссылается иaснаружи. Никакого нового списка не создаётся — поэтому изменение видно везде.
Ключ: операция, которая создаёт новый объект (x += 1 для числа), не трогает оригинал, а операция, которая мутирует объект на месте (.append), трогает. Если внутри g написать lst = lst + [1], то снаружи список тоже НЕ изменится — потому что это создаёт новый список.
Число неизменяемо, список изменяемый. .append мутирует тот же объект, а += у числа создаёт новый.
В Python все аргументы передаются по ссылке, но:
Изменяемые объекты (списки, словари, множества) можно менять внутри функции, и изменения останутся снаружи
Неизменяемые объекты (числа, строки, кортежи) нельзя изменить внутри функции, потому что любая операция создаёт новый объект, а не меняет старый
Потому что список передаётся по ссылке, а число по значению.