python: изменение значения списка в подпрограмме
У меня есть простой пример. Функция test_list_change должна изменить список, переданный ей в качестве параметра. И внутри этой функции есть вызов подпрограммы test_list_change_2, которая должна изменить тот же список.
Проблема в том, что список результатов не содержит изменений, внесенных подпрограммой test_list_change_2
Почему это может быть?
Вот пример:
def test_list_change(lst):
if len(lst) < 3:
lst.append("the last one")
test_list_change_2(lst)
def test_list_change_2(lst):
lst = ["the very last one"]
string_list = ["first", "another one"]
test_list_change(string_list)
print (string_list)
Выход:
["первый", "еще один", "последний"]
5 ответов
Вам нужно на самом деле изменить оригинал list/object
:
def test_list_change(lst):
if len(lst) < 3:
lst.append("the last one")
test_list_change_2(lst)
def test_list_change_2(lst):
lst[:] = ["the very last one"] # changes original list object
string_list = ["first", "another one"]
test_list_change(string_list)
print (string_list)
['the very last one']
Если вы хотите изменить вокруг элементов:
def test_list_change_2(lst):
lst[:-1] = ["the very last one"]
lst[:] = lst[::-1]
string_list = ["first", "another one"]
test_list_change(string_list)
print (string_list)
['the last one', 'the very last one']
Вы можете манипулировать списком любым удобным для вас способом, но на самом деле вам нужно обратиться к исходному объекту списка, переназначение имени не изменится, а просто назначит это имя другому объекту.
Возможно, вы запутались в том, как все работает в python с "передачей по ссылке", и подумали, что, поскольку он передается по ссылке, исходный список следует обновить до ["самого последнего"].
Это работает следующим образом:
1) перед вызовом test_list_change существует имя "string_list", и python создает объект ["first", "another one"], который назначается для string_list
2) теперь в test_list_change новому имени "lst" присваивается ["first", "another one"]. Так что теперь обоим именам присвоен один и тот же объект. Затем он добавляется и изменяется на ['first', 'another', 'last one'], на который указывают string_list и lst
3) В test_list_change_2 перед выполнением назначения существует другое локальное имя lst, которое указывает на ["first", "another one", "ths last one"]. Затем python создает другой объект ['var last one'] и заменяет значение локальной переменной lst.
4) string_list по-прежнему указывает на ['first', 'another', 'last' ']
Иными словами, переменные - это просто передаваемые имена, а объекты управляются "по ссылке".
Ваш test_list_change2
процедура делает lst = ['the very last one']
, Это просто присвоение нового объекта локальному имени lst
, Это никак не влияет на список, переданный этой процедуре.
Я не уверен, что вы пытаетесь достичь. Если ты хочешь test_list_change2
добавить к lst
Просто добавь это. Вы можете уточнить?
Вам нужно вернуть ["the very last one"]
в test_list_change_2
:
def test_list_change_2():
return ["the very last one"]
и назначить результат функции lst
в первой функции:
def test_list_change(lst):
if len(lst) < 3:
lst.append("the last one")
lst= test_list_change_2()
Обратите внимание, что на самом деле вам здесь не нужна функция!!! Вы можете сделать это назначение в первой функции.
Если вы пытаетесь включить в список только "самого последнего", то:
def test_list_change(lst):
if len(lst) < 3:
lst.append("the last one")
lst = test_list_change_2(lst)
def test_list_change_2(lst):
for i in range(len(lst)):
lst.pop()
lst.append("the very last one")
string_list = ["first", "another one"]
test_list_change(string_list)
print (string_list)