Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying python lists

Just when I thought I had understood how Python lists work...

>>> a = [1,2,3]
>>> b = a[:]
>>> b
[1,2,3]
>>> b[1]=100
>>> b
[1,100,3]
>>> a
[1,2,3]

So far,so good. I am initializing b with the contents of a, so that b points to a different object. As a consequence, changes in b don't affect a.

Now take a look at this other example:

>>> a = [[1,2,3],[4,5,6],[7,8,9]]
>>> b = a[:][:]
>>> b
[[1,2,3],[4,5,6],[7,8,9]]
>>> b[1][1] = 100
>>> b
[[1,2,3],[4,100,6],[7,8,9]]
>>> a
[[1,2,3],[4,100,6],[7,8,9]]

Why has the change in b affected a this time? What is different from the previous example?

like image 279
Marcos Gonzalez Avatar asked Jun 13 '13 20:06

Marcos Gonzalez


People also ask

Can you copy a list in Python?

You can copy a list in Python using the copy() method, slicing, the list() method, and a list comprehension. The copy() method is the most direct way of copying a Python list.

How do you copy a list without changing the original Python?

deepcopy() Another key function in the copy module is the deepcopy() function. This function creates a completely independent copy of a list or any other compound object in Python.


2 Answers

The slicing operation x[:] makes a shallow copy. That means, the outer list is different, but is contains the exact same elements. assume a = [[1]]:

b = a[:] # is the same as:
b = [x for x in a]

>>> a[0] is b[0]
True

The double slicing ([:][:]) is doing nothing more than that - again:

b = a[:][:] # is the same as:
b = [y for y in [x for x in a]]

>>> a[0] is b[0]
True

A shallow copy of a shallow copy is, well, a shallow copy.

So b is still a shallow copy of a - these lists are different objects, but they contain identical elements. Then you mutate the inner list in b, but it is the same list in a.

2-level shallow copy can be done with b=[x[:] for x in a]. It extends the same way for n-level copy.

By the way, the term "shallow copy" has the same meaning for any class or container.

If you want real deep copy, you should consider using deep copy.

like image 65
Elazar Avatar answered Sep 30 '22 16:09

Elazar


The silcing [:] makes a shallow copy. but inner objects remain not copied so if they are mutable and You will modified them they will be modified ;) and in both list You will see this

use list comprehension

b = [i[:] for i in a]

or copy.deepcopy()

import copy
b = copy.deepcopy(a)
like image 26
oleg Avatar answered Sep 30 '22 16:09

oleg