Python 如何深度复制列表?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17873384/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to deep copy a list?
提问by Shen
I have some problem with a List copy:
我对 List 副本有一些问题:
So After I got E0
from 'get_edge'
, I make a copy of E0
by calling 'E0_copy = list(E0)'
. Here I guess E0_copy
is a deep copy of E0
, and I pass E0_copy
into 'karger(E)'
. But in the main function.
Why does the result of 'print E0[1:10]'
before the for loop is not the same with that after the for loop?
所以在我得到E0
from 后'get_edge'
,我E0
通过调用'E0_copy = list(E0)'
. 这里我猜E0_copy
是深拷贝E0
,我传E0_copy
进去了'karger(E)'
。但是在主函数中。
为什么'print E0[1:10]'
for循环之前的结果和for循环之后的结果不一样?
Below is my code:
下面是我的代码:
def get_graph():
f=open('kargerMinCut.txt')
G={}
for line in f:
ints = [int(x) for x in line.split()]
G[ints[0]]=ints[1:len(ints)]
return G
def get_edge(G):
E=[]
for i in range(1,201):
for v in G[i]:
if v>i:
E.append([i,v])
print id(E)
return E
def karger(E):
import random
count=200
while 1:
if count == 2:
break
edge = random.randint(0,len(E)-1)
v0=E[edge][0]
v1=E[edge][1]
E.pop(edge)
if v0 != v1:
count -= 1
i=0
while 1:
if i == len(E):
break
if E[i][0] == v1:
E[i][0] = v0
if E[i][1] == v1:
E[i][1] = v0
if E[i][0] == E[i][1]:
E.pop(i)
i-=1
i+=1
mincut=len(E)
return mincut
if __name__=="__main__":
import copy
G = get_graph()
results=[]
E0 = get_edge(G)
print E0[1:10] ## this result is not equal to print2
for k in range(1,5):
E0_copy=list(E0) ## I guess here E0_coypy is a deep copy of E0
results.append(karger(E0_copy))
#print "the result is %d" %min(results)
print E0[1:10] ## this is print2
采纳答案by Sukrit Kalra
E0_copy
is not a deep copy. You don't make a deep copy using list()
(Both list(...)
and testList[:]
are shallow copies).
E0_copy
不是深拷贝。你不使用做出深层副本list()
(两者list(...)
并testList[:]
很浅拷贝)。
You use copy.deepcopy(...)
for deep copying a list.
您copy.deepcopy(...)
用于深度复制列表。
deepcopy(x, memo=None, _nil=[])
Deep copy operation on arbitrary Python objects.
See the following snippet -
请参阅以下片段 -
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = list(a)
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0][1] = 10
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b # b changes too -> Not a deepcopy.
[[1, 10, 3], [4, 5, 6]]
Now see the deepcopy
operation
现在看deepcopy
操作
>>> import copy
>>> b = copy.deepcopy(a)
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b
[[1, 10, 3], [4, 5, 6]]
>>> a[0][1] = 9
>>> a
[[1, 9, 3], [4, 5, 6]]
>>> b # b doesn't change -> Deep Copy
[[1, 10, 3], [4, 5, 6]]
回答by tailor_raj
If your list elements
are immutable objects
then you can use this, otherwise you have to use deepcopy
from copy
module.
如果您list elements
是,immutable objects
那么您可以使用它,否则您必须使用deepcopy
fromcopy
模块。
you can also use shortest way for deep copy a list
like this.
你也可以使用最短的方式进行这样的深拷贝list
。
a = [0,1,2,3,4,5,6,7,8,9,10]
b = a[:] #deep copying the list a and assigning it to b
print id(a)
20983280
print id(b)
12967208
a[2] = 20
print a
[0, 1, 20, 3, 4, 5, 6, 7, 8, 9,10]
print b
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10]
回答by rnbguy
just a recursive deep copy function.
只是一个递归深拷贝函数。
def deepcopy(A):
rt = []
for elem in A:
if isinstance(elem,list):
rt.append(deepcopy(elem))
else:
rt.append(elem)
return rt
Edit: As Cfreak mentioned, this is already implemented in copy
module.
编辑:正如 Cfreak 提到的,这已经在copy
模块中实现了。
回答by ShellayLee
Regarding the list as a tree, the deep_copy in python can be most compactly written as
把列表看成一棵树,python中的deep_copy可以最简洁地写成
def deep_copy(x):
if not isinstance(x, list): return x
else: return map(deep_copy, x)
回答by watashiSHUN
I believe a lot of programmers have run into one or two interview problems where they are asked to deep copy a linked list, however this problem is harder than it sounds!
我相信很多程序员都遇到过一两个面试问题,他们被要求深度复制一个链表,但是这个问题比听起来更难!
in python, there is a module called "copy" with two useful functions
在python中,有一个名为“copy”的模块,有两个有用的功能
import copy
copy.copy()
copy.deepcopy()
copy() is a shallow copy function, if the given argument is a compound data structure, for instance a list, then python will create another object of the same type (in this case, a new list) but for everything inside old list, only their reference is copied
copy() 是一个浅拷贝函数,如果给定的参数是一个复合数据结构,例如一个list,那么 python 将创建另一个相同类型的对象(在这种情况下,一个新的 list)但对于旧列表中的所有内容,只有他们的参考被复制
# think of it like
newList = [elem for elem in oldlist]
Intuitively, we could assume that deepcopy() would follow the same paradigm, and the only difference is that for each elem we will recursively call deepcopy, (just like the answer of mbcoder)
直观地,我们可以假设 deepcopy() 将遵循相同的范式,唯一的区别是对于每个elem 我们将递归调用 deepcopy,(就像 mbcoder 的答案)
but this is wrong!
但这是错误的!
deepcopy() actually preserve the graphical structure of the original compound data:
deepcopy() 实际上保留了原始复合数据的图形结构:
a = [1,2]
b = [a,a] # there's only 1 object a
c = deepcopy(b)
# check the result
c[0] is a # return False, a new object a' is created
c[0] is c[1] # return True, c is [a',a'] not [a',a'']
this is the tricky part, during the process of deepcopy() a hashtable(dictionary in python) is used to map: "old_object ref onto new_object ref", this prevent unnecessary duplicates and thus preserve the structure of the copied compound data
这是棘手的部分,在 deepcopy() 过程中,使用哈希表(python 中的字典)映射:“old_object ref 到 new_object ref”,这可以防止不必要的重复,从而保留复制的复合数据的结构
回答by Kwaw Annor
This is more pythonic
这更pythonic
my_list = [0, 1, 2, 3, 4, 5] # some list
my_list_copy = list(my_list) # my_list_copy and my_list does not share reference now.
NOTE: This is not safe with a list of referenced objects
注意:这对于引用对象列表是不安全的
回答by aljgom
If the contents of the list are primitive data types, you can use a comprehension
如果列表的内容是原始数据类型,则可以使用推导式
new_list = [i for i in old_list]
You can nest it for multidimensional lists like:
您可以将它嵌套在多维列表中,例如:
new_grid = [[i for i in row] for row in grid]
回答by AnupamChugh
Here's an example of how to deep copy a list:
以下是如何深度复制列表的示例:
b = [x[:] for x in a]