我想复制一个列表并修改副本,但是当我尝试这个时,我最终也会修改原始列表。
我的问题的高度简化版本:
list = [2,3,6,8,9,6,7,4,56,8,9,6,7,8]
new_list = list
new_list[2] = 'n'
print list
print new_list
我只想更改新列表的第2项,但是当我尝试这个时,新列表和旧列表都会更改为:
[2,3,'n',8,9,6,7,4,56,8,9,6,7,8]
我在这里缺少一些非常基本的东西吗?
如果我将列表中的每个项目逐个添加到下一个列表中,我可以按照我想要的那样做:
list = [2,3,6,8,9,6,7,4,56,8,9,6,7,8]
new_list = []
for item in list:
new_list.append(item)
new_list[2] = 'n'
print list
print new_list
如果我这样做,只有new_list
更改,但是有更直接的方式吗?
答案 0 :(得分:3)
要制作列表的新副本,请尝试:
newList = list(oldList)
或更多神秘通过切片简明扼要:
newlist = oldList[:]
将 oldList
分配给newList
只会导致两个名称指向同一个对象,如下所示:
copy module提供了通用对象复制功能。 (图片来自:http://henry.precheur.org/python/copy_list)。
答案 1 :(得分:1)
使用new_list = a_list[:]
制作a_list
的浅表副本:
a_list = [2,3,6,8,9,6,7,4,56,8,9,6,7,8]
new_list = a_list[:]
new_list[2] = 'n'
print a_list
print new_list
产量
[2, 3, [6, 8], 9, 6, 7, 4, 56, 8, 9, 6, 7, 8]
[2, 3, [6, 'n'], 9, 6, 7, 4, 56, 8, 9, 6, 7, 8]
将变量名称视为指向对象的引用。
当你说new_list = a_list
时,你告诉Python让new_list
指向a_list
指向的同一个对象。这就是为什么修改new_list
也修改了a_list
。
PS。抵制命名列表list
的诱惑。这会覆盖list
函数的内置定义。
PPS。 new_list = a_list[:]
创建一个浅表副本。如果
a_list = [1, 2,[3,6]]
new_list = a_list[:]
然后
new_list[2][1] = 'n'
会修改a_list
和new_list
中的子列表。如果您想要深层复制,请使用
import copy
new_list = copy.deepcopy(a_list)
代替。
答案 2 :(得分:1)
是的,你缺少一些基本的东西。 Python永远不会复制对象,除非您明确要求它,如myList[:]
。
每当您使用=
时,如同mylist = [2,3,4]
一样,您可以将左侧的名称分配给右侧的值。在这种情况下,您有一个值[2,3,4]
(文字),并为此特定列表"mylist"
指定一个新名称。
当您编写new_list = mylist
时会发生同样的情况:右侧是值,但这次是由其名称给出的。 Python查找此名称并查找现有列表。然后,此列表将获得一个新名称"newlist"
,但您仍然只有一个列表(有两个名称)。
答案 3 :(得分:0)
当你在做什么
new_list = list
您的new_list
实际上并不是新列表,而是对旧列表的新引用。
您可以使用切片表示法创建副本:
>>> l = [1, 2]
>>> l2 = l[:]
>>> l2[0]=42
>>> l
[1, 2]
>>> l2
[42, 2]
另外,请勿使用list
作为变量名称,它与内置list
类型冲突。