0% found this document useful (0 votes)
2 views

Python Tutorial_ Shallow and Deep Copy

This document is a tutorial on shallow and deep copying in Python, explaining how to copy lists and nested lists. It highlights the differences between shallow and deep copies, particularly when dealing with mutable objects like lists and dictionaries. The tutorial provides code examples to illustrate the concepts and emphasizes the importance of using the 'deepcopy' method from the 'copy' module to avoid unintended side effects.

Uploaded by

Sentinel
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Python Tutorial_ Shallow and Deep Copy

This document is a tutorial on shallow and deep copying in Python, explaining how to copy lists and nested lists. It highlights the differences between shallow and deep copies, particularly when dealing with mutable objects like lists and dictionaries. The tutorial provides code examples to illustrate the concepts and emphasizes the importance of using the 'deepcopy' method from the 'copy' module to avoid unintended side effects.

Uploaded by

Sentinel
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1

Python Course

Home Python 2 Tutorial Python 3 Tutorial Advanced Topics Numerical Programming Machine Learning Tkinter Tutorial Contact

Previous Chapter: List Manipulations


Next Chapter: Dictionaries

Shallow and Deep Copy

Follow Bernd Klein,


the author of this
Python 3 Introduction website, at Google+:
Bernd Klein on
Tutorial Google
The Origins of In this chapter, we will cover the question of how to copy lists and nested lists. Trying to copy lists can be a stumping experience for newbies. But before we to summarize some
Bernd Klein on
Python insights from the previous chapter "Data Types and Variables". Python even shows a strange behaviour for beginners of the language - in comparison with some other traditional
Facebook
programming languages - when assigning and copying simple data types like integers and strings. The difference between shallow and deep copying is only relevant for compound
Starting with
objects, i.e. objects containing other objects, like lists or class instances.
Python: The
Interactive Shell Search this website:
In the following code snippet, y points to the same memory location than X. We can see this by applying the id() function on x and y. But unlike "real" pointers like those in C and C++,
Executing a things change, when we assign a new value to y. In this case y will receive a separate memory location, as we have seen in the chapter "Data Types and Variables" and can see in the
Script following example: Go
Indentation
>>> x = 3 This topic in German
Data Types and
>>> y = x
Variables / Deutsche
>>> print(id(x), id(y))
Operators 9251744 9251744 Übersetzung: Flaches
>>> y = 4 und Tiefes Kopieren
Sequential Data
>>> print(id(x), id(y))
Types: Lists and
9251744 9251776 Python 3
Strings >>> print(x,y)
List 3 4
>>> This is a tutorial in
Manipulations
Python3, but this
Shallow and
But even if this internal behaviour appears strange compared to programming languages like C, C++ and Perl, yet the observable results of the assignments answer our expectations. But it can be problematic, if we chapter of our course
Deep Copy is available in a
copy mutable objects like lists and dictionaries.
Dictionaries version for Python
Sets and Frozen Python creates only real copies, if it has to, i.e. if the user, the programmer, explicitly demands it. 2.x as well: Shallow
Sets and Deep Copy in
An Extensive We will introduce you the most crucial problems, which can occur when copying mutable objects, i.e. when copying lists and dictionaries. Python 2.x
Example Using
Sets Training Classes
input via the Copying a list
keyboard This website aims at
Conditional >>> colours1 = ["red", "blue"] providing you with
>>> colours2 = colours1 educational material
Statements
>>> print(colours1) suitable for self-
Loops, while ['red', 'blue'] learning.
Loop >>> print(colours2) Nevertheless, it is
For Loops ['red', 'blue'] faster and more
>>> print(id(colours1),id(colours2))
Difference efficient to attend a
43444416 43444416
between >>> colours2 = ["rouge", "vert"] "real" Python course
interators und >>> print(colours1) in a classroom, with
Iterables ['red', 'blue'] an experienced
>>> print(colours2) trainer. So why not
Output with Print
['rouge', 'vert'] attend one of the live
Formatted output >>> print(id(colours1),id(colours2)) Python courses
with string 43444416 43444200
modulo and the >>>
format method
Functions
Recursion and
Recursive
Functions
Parameter
Passing in
Functions
Namespaces
Global and Local
in Strasbourg, Paris,
Variables
London, Berlin,
Decorators Munich, Hamburg,
Memoization with Frankfurt, or Lake
Decorators Constance by Bernd
Read and Write Klein, the author of
Files this tutorial?
Modular
Programming
and Modules In-house
Packages in Training
Python
Courses
Regular
If you like it, we will
Expressions
come to your
Regular
company or institute
Expressions, and provide a special
In the example above a simple list is assigned to colours1. This list is a so-called "shallow list", because it doesn't have a nested structure, i.e. no sublists are contained in the list. In the next step we assign colour1
Advanced to colours2. training for your
Lambda employees, as we've
Operator, Filter, The id() function shows us that both variables point to the same list object, i.e. they share this object. done it many times in
Reduce and Map Amsterdam (The
List Now we want to see, what happens, if we assign a new list object to colours2. Netherlands), Berlin
(Germany), Bern
Comprehension
As we have expected, the values of colours1 remained unchanged. Like it was in our example in the chapter "Data types and variables" a new memory location had been allocated for colours2, because we have (Switzerland), Basel
Iterators and
assigned a completely new list, i.e. a new list object to this variable. The picture on the left side needs some explanation as well: We have two variable names "colours1" and "colours2", which we have depicted as (Switzerland), Zurich
Generators (Switzerland),
green boxes. The blue box symbolizes the list object. A list object consists of references to other objects. In our example the list object, which is references by both variables, references two string objects, i.e. "red"
Exception Frankfurt (Germany),
and "blue".
Handling Now we have to examine, what will happen, if we change just one element of the list of colours2 or colours1: Locarno
Tests, DocTests, (Switzerland), Den
UnitTests >>> colours1 = ["red", "blue"] Haag (The Hague),
>>> colours2 = colours1 Hamburg, Munich
Object Oriented
>>> print(id(colours1),id(colours2)) (Germany),
Programming 14603760 14603760
Bucharest (Romania),
Class and >>> colours2[1] = "green"
>>> print(id(colours1),id(colours2)) Toronto (Canada),
Instance
14603760 14603760 Edmonton (Canada),
Attributes >>> print(colours1) and many other
Properties vs. ['red', 'green'] cities. We do training
getters and >>> print(colours2) courses in England,
setters ['red', 'green'] Switzerland,
>>>
Inheritance Liechtenstein,
Multiple Austria, Germany,
Let's see, what has happened in detail in the previous code. We assigned a new value to the second
France, Belgium, the
Inheritance element of colours2, i.e. the element with the index 1. Lots of beginners will be stunned that the list
Netherlands,
Magic Methods of colours1 has been "automatically" changed as well. Of course, we don't have two lists: We have
Luxembourg,
and Operator only two names for the same list!
Romania, UK, Italy,
Overloading Spain and other
OOP, Inheritance The explanation is that we didn't assign a new object to colours2. We changed colours2 inside or as it
locations in Europe
is usually called "in-place". Both variables "colours1" and "colours2" still point to the same list object.
Example and in Canada.
Slots
Classes and This way you will get
Class Creation a perfect training up
to your needs and it
Road to Copy with the Slice Operator will be extremely cost
Metaclasses
efficient as well.
Metaclasses It's possible to completely copy shallow list structures with the slice operator without having any of
Metaclass Use the side effects, which we have described above: Contact us so we can
Case: Count find the ideal course
>>> list1 = ['a','b','c','d'] to meet your needs.
Function Calls
>>> list2 = list1[:]
Abstract Classes >>> list2[1] = 'x'
>>> print(list2)
['a', 'x', 'c', 'd'] Skilled Python
Deep and >>> print(list1) Programmers
['a', 'b', 'c', 'd']
Shallow >>>
You are looking for
"Under all speech But as soon as a list contains sublists, we have another difficulty: The sublists are not copied but only the references to the sublists. The following example list "lst2" contains one sublist. We create a shallow copy experienced Python
that is good for with the slicing operator. developers or
anything there lies a programmers? We
silence that is better. >>> lst1 = ['a','b',['ab','ba']] can help you, please
Silence is deep as >>> lst2 = lst1[:] contact us.
Eternity; speech is
shallow as Time." Quote of the
The following diagram depicts the data structure after the copying. We can see that both lst1[2] and lst2[2] point to the same object, i.e. the sublist:
Thomas Carlyle, Day:
(1795 - 1881)
"Only the shallow "Programmers are in
know themselves." a race with the
Oscar Wilde, (1854 - Universe to create
1900) bigger and better
idiot-proof programs,
Copy while the Universe is
trying to create
"Copy from one, it's bigger and better
plagiarism; copy idiots. So far the
from two, it's Universe is winning."
research." (Ananymous)
Wilson Mizner, (1876
- 1933)

This website is Data Protection


supported by: Declaration

Linux and Python Data Protection


Training Courses and Declaration
Seminars

If you assign a new value to the 0th or the 1st index of one of the two lists, there will be no side effect.

>>> lst1 = ['a','b',['ab','ba']]


>>> lst2 = lst1[:]
>>> lst2[0] = 'c'
>>> print(lst1)
['a', 'b', ['ab', 'ba']]
>>> print(lst2)
['c', 'b', ['ab', 'ba']]

Problems arise, if you change one of the elements of the sublist:

>>> lst2[2][1] = 'd'


>>> print(lst1)
['a', 'b', ['ab', 'd']]
>>> print(lst2)
['c', 'b', ['ab', 'd']]

The following diagram depicts the situation after we have executed the code above. We can see that both lst1 and lst2 are affected by the assignment lst2[2][1] = 'd':

Using the Method deepcopy from the Module copy

A solution to the described problems provide the module "copy". This module provides the method "deepcopy", which allows a complete or deep copy of an arbitrary list, i.e. shallow and other lists.

Let's use deepcopy for our previous list:

>>> from copy import deepcopy


>>>
>>> lst1 = ['a','b',['ab','ba']]
>>>
>>> lst2 = deepcopy(lst1)
>>>
>>> lst1
['a', 'b', ['ab', 'ba']]
>>> lst2
['a', 'b', ['ab', 'ba']]
>>> id(lst1)
139716507600200
>>> id(lst2)
139716507600904
>>> id(lst1[0])
139716538182096
>>> id(lst2[0])
139716538182096
>>> id(lst2[2])
139716507602632
>>> id(lst1[2])
139716507615880
>>>

We can see by using the id function that the sublist has been copied, because id(lst2[2]) is different from id(lst1[2]). An interesting fact is that the strings are not copied: lst1[0] and lst2[0] reference the same
string. This is true for lst1[1] and lst2[1] as well, of course.
The following diagram shows the situation after copying the list:

>>> lst2[2][1] = "d"


>>> lst2[0] = "c"
>>> print(lst1)
['a', 'b', ['ab', 'ba']]
>>> print(lst2)
['c', 'b', ['ab', 'd']]
>>>

Now the data structure looks like this:

Previous Chapter: List Manipulations


Next Chapter: Dictionaries

© 2011 - 2018, Bernd Klein, Bodenseo; Design by Denise Mitchinson adapted for python-course.eu by Bernd Klein

You might also like