回答

收藏

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

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

使用new_list = my_list每次都会修改new_list发生变化。my_list为什么会这样?我如何克隆或复制列表以防止它?
" g# f+ _  h  S  _0 D" |                                                               
) J. r2 C3 K6 E: g( B6 e    解决方案:                                                               
& |4 d; ]7 I3 R& G, _                                                                使用new_list = my_list,你实际上没有两个列表。分配正义复制参考列表,而不是实际列表,所以无论如何new_list和my_list指向同一列表。# ~+ }1 N1 w- P+ x; O
实际复制列表的可能性有很多:
% w: H2 z& g  F2 B& O您可以使用内置list.copy()方法(自 Python 3.3 可用):py  new_list = old_list.copy()
0 p5 U+ L8 R/ C. n3 L. T. x可切片:py  new_list = old_list[:]6 s# ^) U* x3 U* [3 |/ s
Alex Martelli 对此的看法(至少早在2007年)是,它是一种奇怪的语法,永远使用它毫无意义。;)(在他看来,下一个更可读)。
( z( a. C/ s3 S3 W& ?: _您可以使用内置list()功能:py  new_list = list(old_list)
  S3 V3 ]9 q' Y, R一般可以用copy.copy():py  import copy  new_list = copy.copy(old_list)! `; y' x& z+ s* s' P# m& T
这比list()因为它必须被发现old_listfirst 数据类型较慢。
/ p, }9 d  S2 Q如果列表包含对象并且您想复制它们,请使用 generic copy.deepcopy():py  import copy  new_list = copy.deepcopy(old_list)
- N& l5 w1 E# R5 Y显然是最慢、最需要内存的方法,但有时是不可避免的。" m" t' r, k0 |, ^: [8 B
例子:1 S1 I0 b0 w5 O$ p
    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))
    6 A$ e$ ?2 u5 B( G, M. L
结果:
3 a. m4 U) X  c: `5 \4 l( B
    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)]5 R% d5 b# H" o- L* b
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则