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

3
以下是代码示例:
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

有人能给我解释一下为什么在后一种情况下,原始列表没有被覆盖,而在第一种情况下却被覆盖了吗?

因为 [:] 创建了一个复制完整列表的切片。 - njzk2
3个回答

4
NumPy数组切片和Python列表切片的工作方式不同。对Python列表进行切片返回列表的浅拷贝,而在NumPy数组上仅返回数组项的视图。
来自NumPy docs
注意,数组的切片不会复制内部数组数据,但也会生成原始数据的新视图。
因此,在您的第一个解决方案中,您可以使用.copy获取数组的副本:
signal_exp_new.append(signal_exp[0].copy())

1
运算符[:]返回序列的切片。对列表进行切片:创建一个新列表,并将原始列表的部分复制到这个新列表中。
没有使用[:],不会创建新列表。signal_exp[0]和signal_exp_new[0]指向同一列表。

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


1
在第一个代码片段中,您使用了指针算术。这意味着您不会将signal_exp [0]中的条目复制到新列表中,而是使用相同的对象并将其“附加”到新变量 - 或在此情况下附加到列表元素。 [:]创建列表的副本(但仅深入一个元素)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接