分配后列表意外更改.为什么会这样,我该如何预防? [英] List changes unexpectedly after assignment. Why is this and how can I prevent it?

查看:56
本文介绍了分配后列表意外更改.为什么会这样,我该如何预防?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 new_list = my_list 时,对 new_list 的任何修改每次都会更改 my_list .为什么会这样,以及如何克隆或复制列表以阻止它?

While using new_list = my_list, any modifications to new_list changes my_list every time. Why is this, and how can I clone or copy the list to prevent it?

推荐答案

使用 new_list = my_list ,您实际上没有两个列表.分配只是将引用复制到列表,而不是实际列表,因此 new_list my_list 都在分配后引用同一列表.

With new_list = my_list, you don't actually have two lists. The assignment just copies the reference to the list, not the actual list, so both new_list and my_list refer to the same list after the assignment.

要实际复制列表,您有多种可能:

To actually copy the list, you have various possibilities:

  • You can use the builtin list.copy() method (available since Python 3.3):

new_list = old_list.copy()

  • 您可以对其进行切片:

  • You can slice it:

    new_list = old_list[:]
    

    Alex Martelli的意见(至少

    Alex Martelli's opinion (at least back in 2007) about this is, that it is a weird syntax and it does not make sense to use it ever. ;) (In his opinion, the next one is more readable).

    您可以使用内置的 list() 函数:

    You can use the built in list() function:

    new_list = list(old_list)
    

  • 您可以使用通用的 copy.copy() :

    import copy
    new_list = copy.copy(old_list)
    

    这比 list()慢一点,因为它必须先找出 old_list 的数据类型.

    This is a little slower than list() because it has to find out the datatype of old_list first.

    如果列表包含对象,并且您也要复制它们,请使用通用 copy.deepcopy() :

    If the list contains objects and you want to copy them as well, use generic copy.deepcopy():

    import copy
    new_list = copy.deepcopy(old_list)
    

    显然是最慢且最需要内存的方法,但有时是不可避免的.

    Obviously the slowest and most memory-needing method, but sometimes unavoidable.

    示例:

    import copy
    
    class Foo(object):
        def __init__(self, val):
             self.val = val
    
        def __repr__(self):
            return 'Foo({!r})'.format(self.val)
    
    foo = Foo(1)
    
    a = ['foo', foo]
    b = a.copy()
    c = a[:]
    d = list(a)
    e = copy.copy(a)
    f = copy.deepcopy(a)
    
    # edit orignal list and instance 
    a.append('baz')
    foo.val = 5
    
    print('original: %r\nlist.copy(): %r\nslice: %r\nlist(): %r\ncopy: %r\ndeepcopy: %r'
          % (a, b, c, d, e, f))
    

    结果:

    original: ['foo', Foo(5), 'baz']
    list.copy(): ['foo', Foo(5)]
    slice: ['foo', Foo(5)]
    list(): ['foo', Foo(5)]
    copy: ['foo', Foo(5)]
    deepcopy: ['foo', Foo(1)]
    

    这篇关于分配后列表意外更改.为什么会这样,我该如何预防?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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