Quantcast
Channel: How do I clone a list so that it doesn't change unexpectedly after assignment? - Stack Overflow
Viewing all articles
Browse latest Browse all 117

Answer by Felix Kling for List changes unexpectedly after assignment. Why is this and how can I prevent it?

$
0
0

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'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).

  • You can use the built in list() function:

    new_list = list(old_list)
  • You can use generic copy.copy():

    import copynew_list = copy.copy(old_list)

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

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

    import copynew_list = copy.deepcopy(old_list)

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

Example:

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))

Result:

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)]

Viewing all articles
Browse latest Browse all 117

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>