Python 将列表的值更改为函数参数

Python 将列表的值更改为函数参数,python,parameter-passing,Python,Parameter Passing,我知道当将列表作为参数发送给函数时,函数中的更改将更改列表,例如: p=[[3, 4], [2, 3]] node=[5,3] def foo(node, p_as_list): p_as_list.append(node) foo(node, p) print(p) #p changes 要停止更改,我使用copy(): 但是如果我像这样改变函数: p=[[3, 4], [2, 3]] node=[5,3] def foo(node, p_as_list): #thi

我知道当将列表作为参数发送给函数时,函数中的更改将更改列表,例如:

p=[[3, 4], [2, 3]]
node=[5,3]

def foo(node, p_as_list):
    p_as_list.append(node)


foo(node, p)
print(p) #p changes
要停止更改,我使用copy():

但是如果我像这样改变函数:

p=[[3, 4], [2, 3]]
node=[5,3]

def foo(node, p_as_list):
    #this line
    p_as_list=p_as_list[-1]
    p_as_list.append(node)

foo(node, p.copy())
print(p) 

p将再次更改,我无法理解为什么会发生这种情况?

一种方法是使用deepcopy

参考库路径:


插入一些调试
print
s有助于识别问题:

p=[[3, 4], [2, 3]]
node=[5,3]

def foo(node, p_as_list):
    #this line
    print('p', id(p_as_list))
    p_as_list=p_as_list[-1]
    print('pm1', id(p_as_list))
    p_as_list.append(node)

print('p', id(p))
print('pm1', id(p[-1]))
foo(node, p.copy())
print(p) 
这张照片是:

p 1872370555144 
pm1 1872370556232
p 1872370108872
pm1 1872370556232
[[3, 4], [2, 3, [5, 3]]]
请注意,
p[-1]
id
没有更改,您可以在相同的
列表上操作。这是因为当您使用
list.copy()
时,只会创建一个浅拷贝

与其复制整个列表,我建议只复制您在函数中修改的部分:


这是因为你做的是肤浅的复制,而不是深奥的复制。您正在复制对那些仍在修改中的内部列表的引用。请看,我需要一种内存高效的方法来传递列表,并且我需要确保列表不会更改,是否有更好的解决方案?我不确定您的确切情况,但您可以尝试复制列表中正在修改的部分。例如,如果执行了
p_as_list=p_as_list[-1].copy()
操作,原始列表将保持不变,并且不会浪费内存复制原始列表的每个方面。您甚至可以删除传递给函数的
p.copy()
部分。
p=[[3, 4], [2, 3]]
node=[5,3]

def foo(node, p_as_list):
    #this line
    print('p', id(p_as_list))
    p_as_list=p_as_list[-1]
    print('pm1', id(p_as_list))
    p_as_list.append(node)

print('p', id(p))
print('pm1', id(p[-1]))
foo(node, p.copy())
print(p) 
p 1872370555144 
pm1 1872370556232
p 1872370108872
pm1 1872370556232
[[3, 4], [2, 3, [5, 3]]]
p=[[3, 4], [2, 3]]
node=[5,3]

def foo(node, p_as_list):
    #this line
    p_as_list=p_as_list[-1].copy()  # copy here!
    p_as_list.append(node)

foo(node, p)  # don't copy here!
print(p)