代码之家  ›  专栏  ›  技术社区  ›  Shaun Han

python类之间的意外继承

  •  0
  • Shaun Han  · 技术社区  · 4 年前

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

    所以在我得到 E0 'get_edge' E0级 'E0_copy = list(E0)' . 我想在这里 E0_copy 是一个深刻的副本 E0级 ,我通过了 进入之内 'karger(E)' . 但在主要功能上。
    为什么 'print E0[1:10]'

    下面是我的代码:

    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
    
    0 回复  |  直到 7 年前
        1
  •  279
  •   Sarthak Ahuja    8 年前

    E0_copy 不是深度复制。你不能用 list() (二者) list(...) testList[:] 是浅拷贝)。

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

    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]]
    
        2
  •  70
  •   Tom Wyllie    6 年前

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

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

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

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

    直观地说,我们可以假设deepcopy()将遵循相同的范例,唯一的区别是对于每个范例 我们将递归地调用deepcopy

    但这是错误的!

    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

        3
  •  20
  •   aljgom Miles    7 年前

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

    new_list = [i for i in old_list]
    

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

    new_grid = [[i for i in row] for row in grid]
    
        4
  •  6
  •   tailor_raj    12 年前

    list elements immutable objects deepcopy copy 模块。

    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]
    
        5
  •  1
  •   Mystic    4 年前

    1号: list() [:] , copy.copy() 都是浅薄的复制品。如果一个物体是复合的,它们都不适合。你需要使用 copy.deepcopy()

    第二条: b = a a b 甚至在改变 .

    将a设置为b

    如果混蛋 b 直接, 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]]
    

    卷影副本

    列表()

    列表() [:] 都是一样的。除第一层更改外,所有其他层的更改都将被传输。

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

    [:]

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

    通过 copy()

    你会发现的 [:] . 他们都是 浅拷贝

    here .

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

    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]]
    
    
        6
  •  0
  •   rnbguy    9 年前

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

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

    copy 模块。

        7
  •  0
  •   AnupamChugh    5 年前

      b = [x[:] for x in a]
    
        8
  •  0
  •   ShellayLee    4 年前

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

    def deep_copy(x):
        if not isinstance(x, list):
            return x
        else:
            return [deep_copy(elem) for elem in x]
    

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

        9
  •  -1
  •   Shubham Kumar    4 年前

    如果不允许直接导入模块,可以将自己的deepcopy函数定义为-

    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
    >>>
    
        10
  •  -2
  •   Kwaw Annor Farshid Ashouri    5 年前

    这更像是蟒蛇

    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.
    

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

    推荐文章