简体   繁体   English

如何传递列表作为值而不是参考?

[英]how to pass a list as value and not as reference?

I have a function that takes a list or numpy array v. The function modify v so also the original vector x changes (because of curse this is a reference). 我有一个采用列表或numpy数组v的函数。该函数修改v,因此原始向量x也会发生变化(因为诅咒这是一个参考)。 I would like to have the old value of x. 我想拥有x的旧值。 There are some easy solutions to this but they do not look very elegant. 有一些简单的解决方案,但是它们看起来并不优雅。

What is the most pythonic way to solvethis problem? 解决此问题的最有效方法是什么?

Let consider for example 让我们考虑一下

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]

Create a copy of the list: 创建列表的副本

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

Python is already giving you the value, the object itself. Python 已经为您提供了值,即对象本身。 You are altering that value by changing its contents. 您正在通过更改其内容来更改该值。

v[:] takes a slice of all indices in the list, creating a new list object to hold these indices. v[:]提取列表中所有索引的一部分,创建一个新的列表对象来保存这些索引。 An alternative way would be to use the list() constructor: 另一种方法是使用list()构造函数:

v = list(v)

Another alternative is to leave the responsibility of creating a copy up to the caller: 另一种选择是将创建副本的责任留给调用者:

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

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

By creating a full copy first, you now have a different value. 通过首先创建完整副本,您现在将获得不同的价值。

Everything in Python is reference. Python中的所有内容都是参考。 If you need an immutable argument, pass a copy. 如果需要一个不可变的参数,请传递一个副本。

A copy can easily be created as v[:] or as list(v) 可以轻松地将副本创建为v[:]list(v)

So your call becomes 所以你的电话变成

z=change_2(x[:])

The first notation, uses the slice notation to create a copy of the list. 第一种表示法,使用切片表示法创建列表的副本。 In case, your list have mutable references within, you would need deepcopy, which can be achieved through copy.deepcopy 如果您的列表中包含可变引用,则需要深度复制 ,可以通过copy.deepcopy实现

For Numpy arrays as @delnan has commented, slice notation returns a view rather than a copy. 对于@delnan注释的Numpy数组,切片符号返回的是视图而不是副本。 To get over it, for numpy arrays use the copy method 要克服它,对于numpy数组,请使用copy方法

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


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

Just create a copy of the list, modify and return the copy 只需创建列表的副本,修改并返回副本

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM