1.5 copying lists#

This lessor describes how to copy a list in Python.

Important

This lesson is still under development.

Suppose we have a list of countries

countries1 = ["Iraq", "Iran", "Lebanon"]
countries2 = countries1

print(countries1)

print(countries2)
['Iraq', 'Iran', 'Lebanon']
['Iraq', 'Iran', 'Lebanon']

Above we have created a new list countries2 and assigned the list countries1 to it. Now both the lists countries1 and countries2 are same. We can check this by checking their memory address.

print(id(countries1),id(countries2))
139691880888640 139691880888640

We can see, 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.

What will happen if we redfine the list countries2?

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

print(countries2)
['Iraq', 'Iran', 'Lebanon']
['Qatar', 'Malaysia', 'Turkey']
print(id(countries1),id(countries2))
139691880888640 139691879375360

Now countries1 and countries2 are different objects. 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 did’t have two lists to begin with. 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.

Question: What will be the output of the following code?

nasalkush_countries = ["us", "uk", "germany"]
istemari_countries = nasalkush_countries

nasalkush_countries.extend(["france"])

print(istemari_countries)

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

Now countries1 and countries2 are not same objects. %% md

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

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

print(id(countries1), id(countries2))

# What about sublists in a list?
139691879762240 139691878991040
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.

We can check that the sublists in both lists (countries1 and countries1) are same objects.

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

The same can problem arisis when use copy method of list object.

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

print(id(countries1), id(countries2))
139691879761344 139691879761664
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]))
139691879824640 139691879824640

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))
139691878991040 139691879834176
print(id(countries1[3]), id(countries2[3]))
139691879834432 139691879834432

using copy module#

from copy import copy

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

print(id(countries1), id(countries2))
139691879376000 139691878991040
print(id(countries1[3]), id(countries2[3]))
139691879836032 139691879836032
from copy import deepcopy

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

countries2 = deepcopy(countries1)

print(id(countries1), id(countries2))
139691879763456 139691879376000

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

print(id(countries1[3]), id(countries2[3]))
139691886054144 139691879825600

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

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

If you don’t understand the above code, don’t worry. We will discuss it later. For now, just remember that if you have a list containing lists, then deepcopy method will not work as expected.

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

Gallery generated by Sphinx-Gallery