如何将列表作为值传递而不是作为引用?

时间:2013-12-21 14:22:03

标签: python list

我有一个带有list或numpy数组v的函数。 函数修改v也使原始向量x改变(因为诅咒这是一个参考)。我想要x的旧值。 有一些简单的解决方案,但它们看起来不太优雅。

解决这个问题最灵活的方式是什么?

让我们考虑一下

def change_2(v):
    v[2]=6
    return v 

x=[1,2,3]
z=change_2(x)
print "x=", x,"z=",z
x= [1, 2, 6] z= [1, 2, 6] #I would like x=[1, 2, 3]

3 个答案:

答案 0 :(得分:3)

创建列表的副本

def change_2(v):
    v = v[:]
    v[2] = 6
    return v

Python 已经为您提供了值,即对象本身。您正在通过更改其内容来更改该值。

v[:]获取列表中所有索引的一部分,创建一个新的列表对象来保存这些索引。另一种方法是使用list()构造函数:

v = list(v)

另一种方法是将创建副本的责任留给调用者:

def change_2(v):
    v[2] = 6
    return v 

x = [1,2,3]
z = change_2(x[:])

首先创建完整副本,您现在拥有不同的值。

答案 1 :(得分:2)

Python中的所有内容都是引用。如果需要不可变参数,请传递副本。

可以轻松地将副本创建为v[:]list(v)

所以你的电话就变成了

z=change_2(x[:])

第一种表示法使用切片表示法来创建列表的副本。 如果您的列表中有可变引用,则需要深度复制,可以通过copy.deepcopy

来实现

对于@delnan评论的Numpy数组,切片表示法返回一个视图而不是一个副本。为了克服它,对于numpy数组使用copy方法

>>> def foo(v):
    v[0] = 1


>>> v = np.zeros(5)
>>> foo(v.copy())
>>> v
array([ 0.,  0.,  0.,  0.,  0.])

答案 2 :(得分:1)

只需创建列表副本,修改并返回副本

def change_2(v):
    w = v[:]      # Create a copy of v
    w[2] = 6      # Modify the copy
    return w      # Return the copy