如何更改列表中的元素,同时保留原始列表的副本?
我在网上查了很多资料,试了很多方法,但就是搞不定这个问题。我觉得问题可能和Python列表的名字有关,列表的名字其实是指向列表,而不是直接就是那个列表,但我还是搞不明白。情况是这样的(这是一个字典的列表):
list_original = [dictionary1, dictionary2, dictionary3]
dictionary2_modified = dictionarymodifier(dictionary2) #some function that modifies the chosen element
list_modified = [i for i in list_original] #makes copy of original list
for i,n in enumerate(dictionary_original):
if i==1:
list_modified[1] = dictionary2_modified #replaces element with modified version
return list_original, list_modified
还有很多类似的情况,但我总是得到原始列表的两个副本,或者新列表的两个副本!我补充一下,我用的是Python 2.4,没办法换版本。
非常感谢任何帮助!
3 个回答
你需要创建一个列表的副本。
copy=list(original)
original[0] = None
你的 dictionarymodifier
真的在原地修改 dictionary2
吗?如果是这样的话,你构建列表的方式就无所谓了。
你只需要用 list_modified = list(list_original)
这样的方法,就能创建一个列表的 浅拷贝。这意味着你可以随意修改这个新列表,但前提是你不能修改原列表里的项目(如果原列表里的东西是不可变的,比如数字或字符串,你就不能修改它们,所以初学者常常把这个搞混,认为这是深拷贝)。
如果你真的需要复制整个列表,可以用 copy.deepcopy
来实现。
可变与不可变
你需要了解可变和不可变元素之间的区别。简单来说,Python中的字典和列表都是可变的。这意味着如果你在一个地方修改了它,其他地方也会跟着改变。
另外,可变类型的变量(比如list
或dict
)可以包含不可变的元素(例如str
),反之亦然:不可变类型的变量(例如tuple
)也可以包含可变的元素(像list
或dict
)。
可变性的例子
下面用列表的例子来展示可变性:
>>> a = [1, 2, 3, 4]
>>> b = a
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>> a[2] = 'x'
>>> a
[1, 2, 'x', 4]
>>> b
[1, 2, 'x', 4]
如何获取列表或字典的副本
要获取list
的副本,你可以这样做:
new_list = old_list[:] # the slicing at the end just takes the whole list
对于dict
,通常这样就足够了:
new_dict = old_dict.copy()
嵌套列表/字典
不过,虽然平坦的列表/字典或者只包含可变元素的列表/字典可以用我刚才说的方法复制,但如果你想复制更复杂的可变数据结构,你需要做一些额外的事情……
在这种情况下,copy
模块里的deepcopy
函数会非常有帮助。copy模块的文档对它的用途有更多说明:
在Python中,赋值语句并不会复制对象,而是创建目标和对象之间的绑定。对于可变的集合或包含可变项目的集合,有时需要复制,以便可以在不改变其他副本的情况下修改一个副本。这个模块提供了通用的浅复制和深复制操作(下面会解释)。