回答

收藏

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

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

使用new_list = my_list每次都会修改new_list发生变化。my_list为什么会这样?我如何克隆或复制列表以防止它?7 i/ N) ]3 K4 w2 O; @
                                                                / H3 @6 O/ P. W0 f' ?* z
    解决方案:                                                                ) l1 z9 p5 D( A  c
                                                                使用new_list = my_list,你实际上没有两个列表。分配正义复制参考列表,而不是实际列表,所以无论如何new_list和my_list指向同一列表。
6 O1 O  p2 K+ G' o实际复制列表的可能性有很多:
& b: C# s$ g/ k4 f5 P) B您可以使用内置list.copy()方法(自 Python 3.3 可用):py  new_list = old_list.copy()- J1 d. m' F8 j  k$ z
可切片:py  new_list = old_list[:]
1 m9 I( H" _% L' k0 z7 gAlex Martelli 对此的看法(至少早在2007年)是,它是一种奇怪的语法,永远使用它毫无意义。;)(在他看来,下一个更可读)。
. `/ C- E- `4 ?" X您可以使用内置list()功能:py  new_list = list(old_list)
( M& s" P7 b* X2 I$ H# Q6 S一般可以用copy.copy():py  import copy  new_list = copy.copy(old_list)2 a# u8 c$ Z# D$ P8 g
这比list()因为它必须被发现old_listfirst 数据类型较慢。
" t3 w8 W8 T$ x. J+ |如果列表包含对象并且您想复制它们,请使用 generic copy.deepcopy():py  import copy  new_list = copy.deepcopy(old_list)
4 h8 v' l, z) Z2 s6 E显然是最慢、最需要内存的方法,但有时是不可避免的。) x# P% h: f9 Q/ J2 }) ?' X( O; ~
例子:
! Q1 U5 r. J5 E% M& h
    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))/ K* w# x5 ]8 \9 T% S! B( [4 }+ w
结果:' t5 Y- \! N7 L# j
    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)], N0 R9 N& H9 O
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则