【问题标题】:Python: operation being unexpectedly propagated along parent listsPython:操作意外地沿父列表传播
【发布时间】:2013-08-29 04:12:35
【问题描述】:

我正在从一个列表中插入和删除元素,该列表是从另一个列表中复制的,我希望保持不变。但是,将操作应用到前者之后,后面的结果也发生了变化。我怎样才能避免这种情况?

这是正在发生的事情的一个例子:

a = range(11)

b = []

for i in a:
    b.append(i+1)

print b
#Out[10]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

c = b
# Here, what I expect is to safely save "b" and work on its copy.

c.insert(-1,10.5)

print c
#Out[13]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5, 11]

c.remove(11)
print c

#Out[15]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5]

# So far everything is right: I inserted and removed what I wanted.
# But then, when I check on my "backed-up b", it has been modified:

print b
#Out[16]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5]

# On the other hand, "a" remains the same; it seems the propagation does not affect
# "loop-parenthood":

print a
# Out[17]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

我不明白为什么该操作会在父列表中传播。我怎样才能避免这种情况?我应该将列表保存为排列,还是应该使用循环创建列表副本?

【问题讨论】:

    标签: python list parent operation propagation


    【解决方案1】:

    您需要使用c = b[:]copy.deepcopy(b) 进行浅拷贝或深拷贝(如果需要递归复制内部对象)。执行c = b,只是创建了一个指向与b 相同的对象的引用,因此,如果b 更改或c 更改,两个变量都会反映这些更改。

    >>> a = range(11)
    >>> b = []
    >>> for i in a:
            b.append(i+1)
    
    
    >>> print b
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    >>> c = b[:]
    >>> c.insert(-1, 10.5)
    >>> print c
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5, 11]
    >>> c.remove(11)
    >>> print c
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5]
    >>> print b
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    

    【讨论】:

    • 这很快!谢谢。
    • 我只是在使用c = b[:] 方法生成的表上运行一个循环。迭代引用了两个表中的元素。最后不仅修改了c,还修改了b。然后我使用了c = copy.deepcopy(b) 方法,似乎应用于c 的循环只影响c 而不是b。所以只有这种方法对我正在做的任务有用。
    • @lag :您必须在其中包含列表或其他可变对象。对于您的示例,c = b[:] 方法应该很好用。下次,请考虑添加上下文,以便在这方面回答问题。
    • 这是真的@Sukrit Kalra,我的列表包括子列表。只是在这里熟悉 Python。对不起我的笨拙。
    【解决方案2】:

    你需要做一个深拷贝:

    import copy 
    
    a = range(11)
    
    b = []
    
    for i in a:
        b.append(i+1)
    
    print b
    #Out[10]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    
    c = copy.deepcopy(b)
    # Here, what I expect is to safely save "b" and work on its copy.
    
    c.insert(-1,10.5)
    
    print c
    #Out[13]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5, 11]
    
    c.remove(11)
    print c
    
    #Out[15]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5]
    
    # So far everything is right: I inserted and removed what I wanted.
    # But then, when I check on my "backed-up b", it has been modified:
    
    print b
    #Out[16]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5]
    
    # On the other hand, "a" remains the same; it seems the propagation do not affect
    # "loop-parenthood":
    
    print a
    

    因为不复制数组,您只是创建了对数组的引用。以下是如何使用副本:

    http://docs.python.org/2/library/copy.html

    【讨论】:

      【解决方案3】:

      使用

      new_list = old_list[:]
      

      new_list = list(old_list)
      

      How to clone or copy a list?

      【讨论】:

        猜你喜欢
        • 2017-01-14
        • 1970-01-01
        • 1970-01-01
        • 2014-11-30
        • 1970-01-01
        • 2013-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多