1.5 copying lists#

Important

This lesson is still under development.

countries1 = ["Pakistan", "Iran", "Turkey"]
countries2 = countries1

print(countries1)

print(countries2)
['Pakistan', 'Iran', 'Turkey']
['Pakistan', 'Iran', 'Turkey']
print(id(countries1),id(countries2))
140715274236864 140715274236864

Both the lists countries1 and countries2 point to same object in memory. This means, even though we have two list variables, in reality we have only one object.

countries2 = ["Qatar", "Malaysia", "Lebanon"]
print(countries1)

print(countries2)
['Pakistan', 'Iran', 'Turkey']
['Qatar', 'Malaysia', 'Lebanon']
print(id(countries1),id(countries2))
140715274236864 140715274238016

So the countries2 list became different from countries1 when we assigned a different object to it. What happens when we change the contents of list

countries1 = ["Pakistan", "Iran", "Turkey"]
countries2 = countries1

countries2[2] = "Syria"

print(countries1)

print(countries2)
['Pakistan', 'Iran', 'Syria']
['Pakistan', 'Iran', 'Syria']

Even though we only changed countries2, the list countries1 changed automatically. This is because, we don’t have two lists in reality. We have one list with two names. What we did was in place change in countries2 list and did not assign a new object to countries2, so the the name countries2 still points to the same object as countries1.

Copying using slicing#

# The above problem can be avoided by using the slice operator
countries1 = ["Pakistan", "Iran", "Turkey"]
countries2 = countries1[:]
countries2[2] = 'Syria'

print(countries1)

print(countries2)
['Pakistan', 'Iran', 'Turkey']
['Pakistan', 'Iran', 'Syria']
print(id(countries1), id(countries2))
140715274646144 140715274237376

Now countries1 and countries2 are not same objects.

# What about sublists in a list?
countries1 = ["Pakistan", "Iran", "Turkey",["Qatar", "Malaysia"]]
countries2 = countries1[:]

print(countries1)

print(countries2)
['Pakistan', 'Iran', 'Turkey', ['Qatar', 'Malaysia']]
['Pakistan', 'Iran', 'Turkey', ['Qatar', 'Malaysia']]
countries2[0] = "Syria"
print(countries1)

print(countries2)
['Pakistan', 'Iran', 'Turkey', ['Qatar', 'Malaysia']]
['Syria', 'Iran', 'Turkey', ['Qatar', 'Malaysia']]
countries2[3][1] = "Iraq"
print(countries1)

print(countries2)
['Pakistan', 'Iran', 'Turkey', ['Qatar', 'Iraq']]
['Syria', 'Iran', 'Turkey', ['Qatar', 'Iraq']]

So again countries1 is changed even though we changed only countries2 list. This is because when we copy a list containing sublists, the sublists are not copied but their reference is copied.

print(id(countries1[3]), id(countries2[3]))
140715274645888 140715274645888

The same can be achieved by using copy method of list object.

countries1 = ["Pakistan", "Iran", "Turkey",["Qatar", "Malaysia"]]
countries2 = countries1.copy()

print(id(countries1), id(countries2))
140715274648448 140715274646400
countries2[3][1] = "Iraq"

print(countries1)

print(countries2)
['Pakistan', 'Iran', 'Turkey', ['Qatar', 'Iraq']]
['Pakistan', 'Iran', 'Turkey', ['Qatar', 'Iraq']]
print(id(countries1[3]), id(countries2[3]))
140715273799808 140715273799808

Using list function#

# The ``list`` function converts a sequence into list, if it is not already a list
countries1 = ["Pakistan", "Iran", "Turkey",["Qatar", "Malaysia"]]
countries2 = list(countries1)

print(id(countries1), id(countries2))
140715274949888 140715274770176
print(id(countries1[3]), id(countries2[3]))
140715274960128 140715274960128

using copy module#

from copy import copy

countries1 = ["Pakistan", "Iran", "Turkey",["Qatar", "Malaysia"]]
countries2 = copy(countries1)

print(id(countries1), id(countries2))
140715274771584 140715274949888
print(id(countries1[3]), id(countries2[3]))
140715274771072 140715274771072
from copy import deepcopy

countries1 = ["Pakistan", "Iran", "Turkey",["Qatar", "Malaysia"]]

countries2 = deepcopy(countries1)

print(id(countries1), id(countries2))
140715274952576 140715274771584

Now countries1 and countries2 are different and also the sublists in both lists are different now.

print(id(countries1[3]), id(countries2[3]))
140715274771328 140715274960704

So if we make change in one sublist, the sublist in other list will not be affected.

countries2[3][1] = "Iraq"

print(countries1)

print(countries2)
['Pakistan', 'Iran', 'Turkey', ['Qatar', 'Malaysia']]
['Pakistan', 'Iran', 'Turkey', ['Qatar', 'Iraq']]

but the strings in them are not copied so they still have same id.

print(id(countries1[0]), id(countries2[0]))
140715274237872 140715274237872

So deepcopy method from copy module is the safest way to copy a list when it contain sublists but it is also the slowest one among others. But what if the two sublists in a list are themselves same objects?

countries1 = ["Pakistan", "Iran"]
b = [countries1,countries1] # there's only 1 object countries1
c = deepcopy(b)

# check the result
c[0] is countries1 # return False, a new object a' is created
False
c[0] is c[1]
True

In such a scenario, copying with nested for loops is the safest way. for loops will be described later.

countries1 = ["Pakistan", "Iran"]
b = [countries1,countries1] # there's only 1 object countries1

c = [[i for i in row] for row in b]
c[0] is countries1
False
c[0] is c[1]
False

Total running time of the script: ( 0 minutes 0.010 seconds)

Gallery generated by Sphinx-Gallery