如何深度复制列表? [英] How to deep copy a list?

查看:29
本文介绍了如何深度复制列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 List 副本时遇到了一些问题:

所以当我从 'get_edge' 得到 E0 后,我通过调用 'E0_copy = list(E0)'.这里我猜E0_copyE0的深拷贝,我把E0_copy传入'karger(E)'.但是在主函数中.
为什么for循环前'print E0[1:10]'的结果和for循环后的结果不一样?

下面是我的代码:

def get_graph():f=open('kargerMinCut.txt')G={}对于 f 中的行:ints = [int(x) for x in line.split()]G[ints[0]]=ints[1:len(ints)]返回 Gdef get_edge(G):E=[]对于 i 在范围内(1,201):对于 G[i] 中的 v:如果 v>i:E.append([i,v])打印 ID(E)返回 Edef karger(E):随机导入计数=200而 1:如果计数 == 2:休息边缘 = random.randint(0,len(E)-1)v0=E[边缘][0]v1=E[边][1]E.pop(边缘)如果 v0 != v1:计数 -= 1我=0而 1:如果我 == len(E):休息如果 E[i][0] == v1:E[i][0] = v0如果 E[i][1] == v1:E[i][1] = v0如果 E[i][0] == E[i][1]:E.pop(i)我-=1我+=1mincut=len(E)返回小剪辑如果 __name__=="__main__":导入副本G = get_graph()结果=[]E0 = get_edge(G)print E0[1:10] ##这个结果不等于print2对于范围内的 k (1,5):E0_copy=list(E0) ##我猜这里E0_coypy是E0的深拷贝结果.追加(karger(E0_copy))#print "结果是 %d" %min(results)打印 E0[1:10] ## 这是打印 2

解决方案

E0_copy 不是深拷贝.您不会使用 list() 进行深层复制.(list(...)testList[:] 都是浅拷贝.)

您使用 copy.deepcopy(...) 用于深度复制列表.

deepcopy(x, memo=None, _nil=[])对任意 Python 对象的深度复制操作.

请参阅以下代码段 -

<预><代码>>>>a = [[1, 2, 3], [4, 5, 6]]>>>b = 列表(a)>>>一种[[1, 2, 3], [4, 5, 6]]>>>乙[[1, 2, 3], [4, 5, 6]]>>>[0][1] = 10>>>一种[[1, 10, 3], [4, 5, 6]]>>>b # b 也发生了变化 ->不是深拷贝.[[1, 10, 3], [4, 5, 6]]

现在看deepcopy操作

<预><代码>>>>导入副本>>>b = copy.deepcopy(a)>>>一种[[1, 10, 3], [4, 5, 6]]>>>乙[[1, 10, 3], [4, 5, 6]]>>>[0][1] = 9>>>一种[[1, 9, 3], [4, 5, 6]]>>>b # b 不会改变 ->深拷贝[[1, 10, 3], [4, 5, 6]]

I have some problem with a List copy:

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?

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

解决方案

E0_copy is not a deep copy. You don't make a deep copy using list(). (Both list(...) and testList[:] are shallow copies.)

You use copy.deepcopy(...) for deep copying a list.

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

>>> 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]]

这篇关于如何深度复制列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆