Передача списка в функцию: по ссылке или по значению?

Из такого примера выходит, что по ссылке:

my_list = ['a', 'b', 'c']

def my_function(values):
    values.append('d')
    print(values)

при вызове my_function с my_list в качестве аргумента ожидаемо видим вывод на печать списка из четырех элементов:

>>> my_function(my_list)
['a', 'b', 'c', 'd']

и измененный my_list:

>>> print(my_list)
['a', 'b', 'c', 'd']

Но если сделать так:

my_list = ['a', 'b', 'c']

def my_function(values):
    values = ['d', 'e']
    print(values)

то выходит, что по значению:

>>> my_function(my_list)
['d', 'e']
>>> print(my_list)
['a', 'b', 'c']

Как, все таки, изменяемые типы передаются в функцию в качестве аргументов?


Ответы (2 шт):

Автор решения: CrazyElf

В переменной values у вас получается ссылка на переданный список. И когда вы в этот список что-то добавляете внутри функции, то данные добавляются в исходный список, на который указывает переменная.

Однако, если вы присвоите внутри функции переменной values ссылку на новый список, это никак не повлияет на тот список, который был передан в функцию - переменная values существует только внутри функции и после такого присвоения она просто потеряет всякую связь с исходным списком.

Это в общем-то так с любыми переменными внутри функции - когда вы им что-то присваиваете, это никак не влияет на те переменные, которые были переданы в функцию. Скорее наоборот тут несколько удивительно, что вы можете менять список, ссылка на который была передана в функцию. Но это именно благодаря тому, что в переменной находится не сам список, а ссылка на него.

→ Ссылка
Автор решения: Danis

В первом примере вы изменяет полученный список, а во втором создаётся новый который никак не связан с my_list

пример:

my_list = ['a', 'b', 'c']

def my_function(values):
    values.append('d')
    return values

print(my_list is my_function(my_list))
my_list = ['a', 'b', 'c']

def my_function(values):
    values = ['d', 'e']
    return values

print(my_list is my_function(my_list))

в первом случае my_list и результат функции это один объект, а во втором два разных

→ Ссылка