Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何深度复制列表?_Python_List_Copy_Deep Copy - Fatal编程技术网

Python 如何深度复制列表?

Python 如何深度复制列表?,python,list,copy,deep-copy,Python,List,Copy,Deep Copy,我对列表副本有一些问题: 因此,在我从'get_edge'获取E0后,我通过调用'E0_copy=list(E0)来复制E0。这里我猜E0\u copy是E0的深度副本,我将E0\u copy传递到'karger(E)中。但是在主功能中。 为什么for循环之前的“print E0[1:10]”的结果与for循环之后的结果不同 下面是我的代码: def get_graph(): f=open('kargerMinCut.txt') G={} for line in f:

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

因此,在我从
'get_edge'
获取
E0
后,我通过调用
'E0_copy=list(E0)
来复制
E0
。这里我猜
E0\u copy
E0
的深度副本,我将
E0\u 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

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

如果您的
列表元素
不可变对象
,那么您可以使用它,否则您必须使用
copy
模块中的
deepcopy

您也可以像这样使用最短路径对
列表进行深度复制

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]

只是一个递归的深度复制函数

def deepcopy(A):
    rt = []
    for elem in A:
        if isinstance(elem,list):
            rt.append(deepcopy(elem))
        else:
            rt.append(elem)
    return rt

编辑:正如Cfreak提到的,这已经在
copy
模块中实现了。

将列表视为一棵树,python中的deep\u copy可以最简洁地写成

def deep_拷贝(x):
如果不存在(x,列表):
返回x
其他:
返回[x中元素的深拷贝(元素)]

它基本上是以深度优先的方式递归遍历列表。

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

在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中的字典)映射: “旧的对象引用到新的对象引用”,这可以防止不必要的重复,从而保留复制的复合数据的结构

这更像蟒蛇

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.

注意:这对于引用对象列表是不安全的

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

new_list = [i for i in old_list]
您可以将其嵌套为多维列表,如:

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

下面是一个如何深度复制二维列表的示例:

  b = [x[:] for x in a]
@苏克里特·卡拉

第一:
list()
[:]
copy.copy()
都是浅拷贝。如果一个物体是复合物,它们都不合适。您需要使用
copy.deepcopy()

第二:
b=a
直接,
a
b
具有相同的参考,更改
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]]
卷影副本 通过
list()
list()
[:]
是相同的。除第一层更改外,所有其他层的更改都将被传输

>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]]
通过
[:]
>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]]
list()和[:]更改除第一层以外的其他层
#=============[:]===========
>>>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]]
#=============列表()===========
>>>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]]
通过
copy()
您将发现
copy()
函数与
list()
[:]
相同。它们都是浅拷贝

有关浅拷贝和深拷贝的更多信息,请参考
def copyList(L):
if type(L[0]) != list:
    return [i for i in L]
else:
    return [copyList(L[i]) for i in range(len(L))]
>>> x = [[1,2,3],[3,4]]
>>> z = copyList(x)
>>> x
[[1, 2, 3], [3, 4]]
>>> z
[[1, 2, 3], [3, 4]]
>>> id(x)
2095053718720
>>> id(z)
2095053718528
>>> id(x[0])
2095058990144
>>> id(z[0])
2095058992192
>>>