我绝对傻到为什么会发生以下情况:
这是我的代码:
def add_one(array):
new_array = array
length = len(array)
for i in range(length):
new_array[i] = new_array[i]+1
return new_array
x = [1,2,3,4,5];
y = add_one(x)
print x
print y
结果如下:
[2, 3, 4, 5, 6]
[2, 3, 4, 5, 6]
我不明白为什么x会改变。
我的推测: 不知何故,x作为函数add_one的全局变量给出。我包含'new_array = array',这样如果数组不知何故是全局变量x,x就不会被改变。但是,当'new_array = array'被执行时,不知何故new_array也变成了全局变量x。我写了一个替代版本的函数add_one,它没有给我带来问题:
def add_one(array):
new_array = []
length = len(array)
for i in range(length):
new_array.append(array[i]+1)
似乎如果局部变量(即数组)是由函数中的索引编辑的,那么它相对于作为该函数输入的全局变量会变为全局变量吗?
我不知道发生了什么事。任何解释都将受到高度赞赏。
答案 0 :(得分:6)
当你说new_array = array
时,你没有复制数组,你只是在为数组创建另一个名称。这两个名称仍适用于同一阵列。
要制作副本,最简单的方法是使用切片:new_array = array[:]
答案 1 :(得分:4)
对于模糊的读者来说,没有什么是全球性的。 array
仍然是一个完全正常的局部变量。但它是一个参考,因为Python中的所有东西(好吧,至少每个名字)都是一个参考:
add_one(x)
传递引用(不像C ++中的引用,更像是指针 - 如果其中任何一个对您来说意味着什么)到x
到add_one
new_array = array
只会复制该引用这意味着在array
中add_one
调用方法修改了调用者的同一个对象x
,指的是 - 重新分配array
({{1}只会覆盖引用的本地副本而不会影响引用同一对象的其他变量(毕竟,很可能没有这样的变量!),但成员或项目赋值(例如array = []
)基本上是方法调用,将修改对象。
通常,从现有的列表生成新列表的最简单方法是使用列表推导,其中某些修改模式应用于每个元素,并且可选地进行一些过滤。在此示例中为new_array[i] = ...
。
答案 2 :(得分:1)
在第三行,您将y设置为x。
new_array = array
答案 3 :(得分:0)
这一行至关重要:
new_array = array
您必须将new_array
视为新变量,而不是变量(对象)的新名称,其名称为array
。