如何深度复制列表?

2024-06-01 02:17:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我对列表副本有一些问题:

因此,在我从'get_edge'获得E0之后,我通过调用'E0_copy = list(E0)'来复制E0。这里我猜E0_copyE0的一个深度副本,我将E0_copy传递到'karger(E)'。但在主功能中。
为什么for循环之前的'print E0[1:10]'的结果与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

Tags: inforgetlenifisdefv1
3条回答

我相信很多程序员都遇到过一两个面试问题,要求他们深度复制一个链接列表,然而这个问题比听起来更难

在python中,有一个名为“copy”的模块,其中包含两个有用的函数

import copy
copy.copy()
copy.deepcopy()

copy()是一个浅层复制函数,如果给定的参数是一个复合数据结构,例如列表,那么python将创建另一个相同类型的对象(在本例中是新列表),但对于旧列表中的所有内容,只复制它们的引用

# think of it like
newList = [elem for elem in oldlist]

直观地说,我们可以假设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'']

这是一个棘手的部分,在deepcopy()过程中,使用哈希表(python中的字典)映射: “旧的对象引用到新的对象引用”,这可以防止不必要的重复,从而保留复制的复合数据的结构

official doc

如果列表的内容是基本数据类型,则可以使用

new_list = [i for i in old_list]

您可以将其嵌套为多维列表,如:

new_grid = [[i for i in row] for row in grid]

E0_copy不是深度副本。您不能使用list()进行深度复制。(无论是list(...)还是testList[:]都是浅拷贝。)

使用^{}深度复制列表

deepcopy(x, memo=None, _nil=[])
    Deep copy operation on arbitrary Python objects.

请参阅以下代码片段-

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

现在查看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]]

相关问题 更多 >