Python:列表被覆盖。但为什么?

时间:2014-02-14 14:09:07

标签: python arrays list numpy

以下代码:

file_path = 'some_path/data.txt'
exp = loadtxt(file_path)

signal_exp = []
signal_exp.append(exp[1, :])

signal_exp_new = []
signal_exp_new.append(signal_exp[0])

signal_exp_new[0][0:800] = 0.0

将导致signal_exp覆盖前800个元素以及signal_exp_new。我找到了解决方案,但我不明白为什么下一个工作按预期工作(至少对我来说):

file_path = 'some_path/data.txt'
exp = loadtxt(file_path)

signal_exp = []
signal_exp.append(exp[0, :].tolist())

signal_exp_new = []
signal_exp_new.append(signal_exp[0][:])

for l in range(800):
    signal_exp_new[0][l] = 0.0

任何人都可以给我一个解释为什么在后一种情况下,原始列表不会被覆盖,但在第一种情况下它是?

3 个答案:

答案 0 :(得分:3)

NumPy数组切片和Python列表切片的工作方式不同。在Python列表上切片会返回列表的浅表副本,而在NumPy数组上,它只返回数组项的视图。

来自NumPy docs

  

请注意,数组切片不会复制内部数组数据   还可以生成原始数据的新视图。

因此,在您的第一个解决方案中,您可以使用.copy获取数组的副本:

signal_exp_new.append(signal_exp[0].copy())

答案 1 :(得分:1)

运算符[:]返回序列的切片。切片列表的一部分:创建一个新列表,并将原始列表的一部分复制到这个新列表中。

如果没有[:],则不会创建新列表。 signal_exp [0]和signal_exp_new [0]指的是同一个列表。

http://henry.precheur.org/python/copy_list

答案 2 :(得分:1)

在你使用指针arithmethic的第一个片段中。这意味着您不会将条目从signal_exp[0]复制到新列表,但它使用相同的对象并将其“附加”到新变量 - 或者在这种情况下“附加”到列表元素。 [:]创建列表的副本(但只有一个元素深)。