Python列表问题

时间:2011-09-12 17:19:07

标签: python

我遇到python列表问题。简化版本是:

mylist1 = [...some items in a list...]

mylist2 = mylist1

mylist1.pop(i)

mylist.insert(i,item)

print(mylist1)

print(mylist2)

问题是我希望mylist2保留mylist1的原始版本。这个问题有解决方法吗?

6 个答案:

答案 0 :(得分:5)

您需要制作一份副本,而不是将mylist2分配给mylist1。这可以通过使用list构造函数来完成:

mylist2 = list(mylist)

或通过copy.copy()(或copy.deepcopy()):

import copy
mylist2 = copy.copy(mylist)

copy模块可用于复制其他对象(例如:dict s)并制作深层副本。
请参阅difference between a shallow and a deep copy上的此Wiki页面。

最后是切片语法:

mylist2 = mylist[:]

但我个人个人因为here列出的原因而避免使用这种相当神秘的语法。

答案 1 :(得分:2)

使用

mylist2 = mylist1[:]

copy库,适用于您需要对象的浅(copy.copy(x))或深拷贝(copy.deepcopy(x))的更复杂案例

请注意,简单副本不适用于列表列表:

>> x =[[1,2,3], [4,5,6]]
>> import copy
>> y = copy.copy(x)
>> y
[[1, 2, 3], [4, 5, 6]]
>> x[1][1]= 'oo'
>> x
[[1, 2, 3], [4, 'oo', 6]]
>> y
[[1, 2, 3], [4, 'oo', 6]]

修改
来自Mark Lutz的Learning Python 4 ed,p.150:

  

有多种方法可以复制列表,包括使用   内置列表功能和标准库复制模块。的也许   最常见的方法是从头到尾切片

答案 2 :(得分:1)

您需要制作mylist1的浅表副本。

mylist2 = mylist1[:]

有关详细信息,请参阅this blog post

但是,如果列表包含其他列表或对象,并且您希望以递归方式复制这些列表或对象,则需要执行deep copy

from copy import deepcopy
mylist2 = deepcopy(mylist)

脚注

我不明白为什么提到标准mylist[:]成语的所有答案(见introduction to List中的第3段)都被低估了。

对于它的价值,使用切片表示法进行复制似乎是最快的方法(无论如何我的Python版本.YMMV)。

[me@home]$ python -V
Python 2.6.6
[me@home]$ python -m timeit "L1 = range(100000)" "L2 = L1[:]"
100 loops, best of 3: 3 msec per loop
[me@home]$ python -m timeit "L1 = range(100000)" "L2 = list(L1)"
100 loops, best of 3: 3.86 msec per loop
[me@home]$ python -m timeit "from copy import copy; L1 = range(100000)" "L2 = copy(L1)"
100 loops, best of 3: 3.95 msec per loop

那就是说,我同意list(mylist)mylist[:]更适合初学者。然而,两者都是有效的,并且在野外使用,我不明白为什么初学者应该与其中一个绝缘。

答案 3 :(得分:1)

使用

mylist2 = mylist1[:]

而不是

mylist2 = mylist1

这是制作列表副本的标准习惯用法。

答案 4 :(得分:0)

这是由python的浅拷贝/深拷贝引起的。也称为指针。

这是因为列表是指向数据结构的指针。所以如果我们有这样的记忆:

1    2    3    4    5
A    B    C    D    E

所以,如果我们有一个值为1的指针,如果我们取消引用它,我们就会得到A。现在,如果我们在指针中复制值,我们会1而不是A,因为我们没有得到它指向的而我们的新变量将指向和旧的存储空间相同。

我们要么需要使用深层拷贝库,要么使用标准的python习惯用法mylist2 = mylist1[:]来获取内容的副本,而不是复制实际驻留在mylist1中的内存地址。< / p>

答案 5 :(得分:0)

我们可以使用循环创建新列表,然后我们可以更改第二个元素的列表:

mylist1=[......]
mylist2=[]
for i in mylist1:
mylist2+[i]

mylist1.pop(..)
mylist1.insert(....,...)
print(mylist1)
print(mylist2)