She*_*hen 111 python copy list deep-copy
我对List副本有一些问题:
所以我E0来之后'get_edge',我E0打电话给我'E0_copy = list(E0)'.在这里,我想E0_copy是的深层副本E0,和我通E0_copy入'karger(E)'.但在主要功能.
为什么'print E0[1:10]'for循环之前的结果与for循环之后的结果不一样?
以下是我的代码:
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
Run Code Online (Sandbox Code Playgroud)
Suk*_*lra 189
E0_copy不是一个深刻的副本.你不使用深层副本list()(两者list(...)并testList[:]很浅拷贝).
您copy.deepcopy(...)用于深度复制列表.
deepcopy(x, memo=None, _nil=[])
Deep copy operation on arbitrary Python objects.
Run Code Online (Sandbox Code Playgroud)
请参阅以下代码段 -
>>> 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]]
Run Code Online (Sandbox Code Playgroud)
现在看看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]]
Run Code Online (Sandbox Code Playgroud)
wat*_*HUN 54
我相信很多程序员遇到了一两个面试问题,他们被要求深层复制一个链表,但这个问题并不像听起来那么容易!
在python中,有一个名为"copy"的模块,它有两个有用的功能
import copy
copy.copy()
copy.deepcopy()
Run Code Online (Sandbox Code Playgroud)
copy()是一个浅复制函数,如果给定的参数是一个复合数据结构,例如一个列表,那么python将创建另一个相同类型的对象(在本例中是一个新列表),但对于旧列表中的所有内容,只复制他们的参考
# think of it like
newList = [elem for elem in oldlist]
Run Code Online (Sandbox Code Playgroud)
直觉上,我们可以假设deepcopy()将遵循相同的范例,唯一的区别是对于每个元素我们将递归调用deepcopy,(就像mbcoder的答案一样)
但这是错的!
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'']
Run Code Online (Sandbox Code Playgroud)
这是一个棘手的部分,在deepcopy()过程中,一个哈希表(python中的字典)用于映射:"old_object ref into new_object ref",这可以防止不必要的重复,从而保留复制的复合数据的结构
Mys*_*tic 14
@苏克里特卡尔拉
No.1:list()、[:]、copy.copy()都是浅拷贝。如果一个对象是复合的,那么它们都不适合。你需要使用copy.deepcopy().
第二:b = a直接,a并且b有相同的引用,改变a就等于改变b。
如果直接分配a,b并a共享b一个参考。
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = a
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0] = 1
>>> a
[1, [4, 5, 6]]
>>> b
[1, [4, 5, 6]]
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = 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
[[1, 10, 3], [4, 5, 6]]
Run Code Online (Sandbox Code Playgroud)
list()list()并且[:]是相同的。除了第一层的更改外,所有其他层的更改都将被转移。
>>> 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
>>> a
[1, [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> 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
[[1, 10, 3], [4, 5, 6]]
Run Code Online (Sandbox Code Playgroud)
[:]>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = a[:]
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0] = 1
>>> a
[1, [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = 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
[[1, 10, 3], [4, 5, 6]]
Run Code Online (Sandbox Code Playgroud)
# =========== [:] ===========
>>> a = [[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b = a[:]
>>> a
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> a[0][2] = 4
>>> a
[[1, 2, 4], [4, 5, 6]]
>>> b
[[1, 2, 4], [4, 5, 6]]
>>> a = [[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b = a[:]
>>> a
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> a[0][2][0] = 999
>>> a
[[1, 2, [999, 6]], [4, 5, 6]]
>>> b
[[1, 2, [999, 6]], [4, 5, 6]]
# =========== list() ===========
>>> a = [[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b = list(a)
>>> a
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> a[0][2] = 4
>>> a
[[1, 2, 4], [4, 5, 6]]
>>> b
[[1, 2, 4], [4, 5, 6]]
>>> a = [[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b = list(a)
>>> a
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> a[0][2][0] = 999
>>> a
[[1, 2, [999, 6]], [4, 5, 6]]
>>> b
[[1, 2, [999, 6]], [4, 5, 6]]
Run Code Online (Sandbox Code Playgroud)
copy()您会发现该功能与和copy()相同。它们都是浅拷贝。list()[:]
有关浅复制和深复制的更多信息,也许您可以参考这里。
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = copy.copy(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
[[1, 10, 3], [4, 5, 6]]
Run Code Online (Sandbox Code Playgroud)
deepcopy()>>> import copy
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = copy.deepcopy(a)
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0] = 1
>>> a
[1, [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = copy.deepcopy(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
[[1, 2, 3], [4, 5, 6]]
Run Code Online (Sandbox Code Playgroud)
alj*_*gom 10
如果列表的内容是原始数据类型,则可以使用理解
new_list = [i for i in old_list]
Run Code Online (Sandbox Code Playgroud)
您可以将其嵌套为多维列表,例如:
new_grid = [[i for i in row] for row in grid]
Run Code Online (Sandbox Code Playgroud)
如果您list elements是,immutable objects那么您可以使用它,否则您必须使用deepcopyfromcopy模块。
你也可以使用最短的方式进行这样的深拷贝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]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
186067 次 |
| 最近记录: |