如果切片不创建列表副本也不创建list()如何获得列表的真实副本?

时间:2009-06-04 00:40:53

标签: python list copy

我正在尝试修改列表,因为我的修改有点棘手而且我的列表很大我使用以下代码获取了我的列表

tempList=origList[0:10]
for item in tempList:
    item[-1].insert(0 , item[1])
    del item[1]

我这样认为对列表的所有修改都会影响tempList对象而不是origList对象。

一旦我的代码正确并在原始列表中运行,前十个项目(索引0-9)受到我测试上面打印的代码的操作的影响。

所以我用谷歌搜索了一下,我找到了一些参考文献,说采取切片复制列表并创建一个新的。我还找到了帮助我找到项目ID的代码,所以我从头开始创建了我的origList,获得了前十项的ID。我再次对列表进行切片,发现切片中的id与origList的前十项中的id匹配。

我发现更多的注释表明复制列表的更加pythonic的方法是使用

tempList=list(origList([0:10])

我试过了,我仍然发现tempList中的id与origList中的id匹配。

请不要建议更好的方法来进行编码 - 我将在列表中了解如何在我理解复制如何工作后自己理解

根据Kai的回答,正确的方法是:

import copy
tempList=copy.deepcopy(origList[0:10])
id(origList[0])
>>>>42980096
id(tempList[0])
>>>>42714136

像魅力一样工作

2 个答案:

答案 0 :(得分:24)

切片会创建浅色副本。在您的示例中,我看到您在insert()上调用item[-1],这意味着该项是列表列表。这意味着您的浅拷贝仍然引用原始对象。您可以将其视为制作指针的副本,而不是实际的对象。

您的解决方案在于使用深层副本。 Python只提供copy module这类东西。当你搜索它时,你会发现有关浅层和深层复制的更多信息。

答案 1 :(得分:4)

如果复制对象,则不会复制其内容。在大多数情况下,这就是你想要的。在您的情况下,您必须确保自己复制内容。您可以使用copy.deepcopy但如果您有一个列表或类似的东西,我建议使用copy = [l[:] for l in list_of_lists],这应该快得多。

你的代码风格的一点注意事项:

  • del是一个声明,而不是一个函数,因此最好不要在那里使用parens,它们只会令人困惑。
  • 操作符周围的空格和逗号后的空格会使代码更易于阅读。
  • list(alist)复制一个列表,但它不比alist [:]更pythonic,我认为alist [:]比替代更常用。