回答

收藏

分配后列表意外更改,我该如何预防?

技术问答 技术问答 493 人阅读 | 0 人回复 | 2023-09-12

使用new_list = my_list每次都会修改new_list发生变化。my_list为什么会这样?我如何克隆或复制列表以防止它?7 @2 t! h5 n- w' h; ~
                                                               
7 k. i" q4 i+ d! X. {5 ~& Q    解决方案:                                                                5 G( `. u% w) S
                                                                使用new_list = my_list,你实际上没有两个列表。分配正义复制参考列表,而不是实际列表,所以无论如何new_list和my_list指向同一列表。! y  S) W7 S! b  d2 T3 o+ V$ U" Y# @
实际复制列表的可能性有很多:; d% [1 o& q4 h) w1 [  R  V
您可以使用内置list.copy()方法(自 Python 3.3 可用):py  new_list = old_list.copy(). B2 u" B5 z3 j
可切片:py  new_list = old_list[:]! I" ?( n0 R. P& W( A1 k
Alex Martelli 对此的看法(至少早在2007年)是,它是一种奇怪的语法,永远使用它毫无意义。;)(在他看来,下一个更可读)。
9 l6 h$ Z# x) Z$ w您可以使用内置list()功能:py  new_list = list(old_list)
/ _* r/ w, T# O1 g0 w一般可以用copy.copy():py  import copy  new_list = copy.copy(old_list)
5 j, V- ~6 h" G% _* A这比list()因为它必须被发现old_listfirst 数据类型较慢。
& X$ s: A. E1 ]% H如果列表包含对象并且您想复制它们,请使用 generic copy.deepcopy():py  import copy  new_list = copy.deepcopy(old_list)
7 u$ s' g4 H) {% B6 S+ R% Y& k" A显然是最慢、最需要内存的方法,但有时是不可避免的。
! |$ k& ~8 i4 R) F) Y/ N) j例子:1 ?8 I. l' O' G1 A' `  l3 a
    import copyclass 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 = 5print('original: %r\nlist.copy(): %r\nslice: %r\nlist(): %r\ncopy: %r\ndeepcopy: %r       % (a,b,c,d,e,f))" T5 K) U" `2 S
结果:
4 B3 M5 f5 l$ y! ]0 S
    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)]
    ; N- c" X7 M, g  J, h" F
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则