• Python »
  • 3.12.3 Documentation »
  • The Python Standard Library »
  • Data Types »
  • copy — Shallow and deep copy operations
  • Theme Auto Light Dark |

copy — Shallow and deep copy operations ¶

Source code: Lib/copy.py

Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other. This module provides generic shallow and deep copy operations (explained below).

Interface summary:

Return a shallow copy of x .

Return a deep copy of x .

Raised for module specific errors.

The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):

A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.

A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

Two problems often exist with deep copy operations that don’t exist with shallow copy operations:

Recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop.

Because deep copy copies everything it may copy too much, such as data which is intended to be shared between copies.

The deepcopy() function avoids these problems by:

keeping a memo dictionary of objects already copied during the current copying pass; and

letting user-defined classes override the copying operation or the set of components copied.

This module does not copy types like module, method, stack trace, stack frame, file, socket, window, or any similar types. It does “copy” functions and classes (shallow and deeply), by returning the original object unchanged; this is compatible with the way these are treated by the pickle module.

Shallow copies of dictionaries can be made using dict.copy() , and of lists by assigning a slice of the entire list, for example, copied_list = original_list[:] .

Classes can use the same interfaces to control copying that they use to control pickling. See the description of module pickle for information on these methods. In fact, the copy module uses the registered pickle functions from the copyreg module.

In order for a class to define its own copy implementation, it can define special methods __copy__() and __deepcopy__() . The former is called to implement the shallow copy operation; no additional arguments are passed. The latter is called to implement the deep copy operation; it is passed one argument, the memo dictionary. If the __deepcopy__() implementation needs to make a deep copy of a component, it should call the deepcopy() function with the component as first argument and the memo dictionary as second argument. The memo dictionary should be treated as an opaque object.

Discussion of the special methods used to support object state retrieval and restoration.

Previous topic

types — Dynamic type creation and names for built-in types

pprint — Data pretty printer

  • Report a Bug
  • Show Source

Python: Deep and Shallow Copy Object

does python assignment copy

  • Introduction

In this article, we'll take a look at how to deep and shallow copy the objects in Python.

The short answer is that you can use methods of the copy module, for both operations:

Though, what does it mean to copy something in a shallow or deep fashion?

In the proceeding sections, we'll dive into what these terms mean, how Python treats object references and objects in memory, and why these two methods work the way they do.

  • Shallow Copy an Object in Python

When we use assignment statements ( = ) in Python to create copies of compound objects, such as lists or class instances or basically any objects that contain some other objects, Python does not clone the object itself. Instead, it simply binds the reference to the targeted object.

Imagine that we have a list with the following elements in it:

If we try to copy our original list using the assignment statement as follows:

It may look like that we cloned our object and now have two of them:

But, do we really have two objects? No, we don't. We have two reference variables pointing to the same object in memory. This can easily be verified by printing the ID of the object in memory for both of these:

A more tangible proof of this can be observed by attempting to change a value in either of "the two lists" - while in reality, we change the same list, and both pointers point to the same object in memory.

Let's access the last element of the object pointed to by original_list :

This results in:

Knowing that both reference variables point to the same object, printing shallow_copy_list will return the same result:

Shallow Copying is the process of copying a reference to an object and storing it in a new variable. The original_list and shallow_copy_list are merely references that point to the same addresses in memory (RAM), that store the values of [[1, 2, 3], [4, 5, 6], ['X', 'Y', 'ZZZ']] .

An illustration of the shallow copy

It is also possible to create a shallow copy of an object using a slice of the entire list and assignment statement:

Another way to shallow copy is to use the copy module of Python’s standard library.

To use the copy module, we must first import it:

Now we can use the copy() method of the copy module:

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

Print them both to see that if they reference the same values:

As expected, they do:

Usually, you would want to copy a compound object, for example at the beginning of a method, then modify the clone, but keep the original object as it was in order to use it again later sometime.

To achieve this, we need to deep copy the object. Now let's learn what is a deep copy and how to deep copy a compound object.

  • Deep Copy an Object in Python
Deep copying an object means really cloning the object and its values into a new copy (instance) in memory, with those same values.

Rather than creating a new reference to the same values, with the deep copy, we can actually create a new object that is independent of the original data but contains the same values.

In a typical deep copy process, first, a new object reference is created, then all the child objects are added to the parent object recursively.

This way, unlike a shallow copy, making any modification to the original object, does not reflect in the copy object (or vice versa).

Here is a simple illustration of a typical deep copy:

An illustration of the deep copy

To deep copy an object in Python, we use the deepcopy() method of the copy module.

Let's import the copy module and create a deep copy of a list:

Now let's print our lists to make sure the outputs are the same, as well as their IDs as proof of their uniqueness:

The output confirms that we've created ourselves a genuine copy:

Now let's try to modify our original list by changing the last element of the last list to the "O", and then print it to see the result:

We get the results as expected:

Now if we go ahead and try to print our copy list:

The previous modification did not reflect on this list:

Remember that the copy() and deepcopy() methods are applicable on other compound objects. This means that you can use them to create copies of class instances as well.

In this article, we learned what it means to shallow copy and to deep copy an object.

We also learned that we can use the copy() method of the copy module to create a shallow copy, and the deepcopy() method to create a deep copy of the compound objects.

You might also like...

  • Hidden Features of Python
  • Python Docstrings
  • Handling Unix Signals in Python
  • The Best Machine Learning Libraries in Python
  • Guide to Sending HTTP Requests in Python with urllib3

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

Full-stack software developer. Python, C#, Linux.

In this article

does python assignment copy

Building Your First Convolutional Neural Network With Keras

Most resources start with pristine datasets, start at importing and finish at validation. There's much more to know. Why was a class predicted? Where was...

David Landup

Data Visualization in Python with Matplotlib and Pandas

Data Visualization in Python with Matplotlib and Pandas is a course designed to take absolute beginners to Pandas and Matplotlib, with basic Python knowledge, and...

© 2013- 2024 Stack Abuse. All rights reserved.

Shallow and deep copy in Python: copy(), deepcopy()

In Python, you can make a shallow and deep copy using the copy() and deepcopy() functions from the copy module. A shallow copy can also be made with the copy() method of lists, dictionaries, and so on.

  • copy — Shallow and deep copy operations — Python 3.11.3 documentation

Shallow copy and deep copy in Python

Assignment to another variable, copy() method of list, dictionary, etc., list() , dict() , etc., copy.copy(), deep copy: copy.deepcopy().

The following is a summary of the differences between assignment to another variable, shallow copy, and deep copy.

The Python official documentation describes shallow copy and deep copy as follows:

The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances): A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original. A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original. copy — Shallow and deep copy operations — Python 3.11.3 documentation

When objects are contained within mutable objects, like elements in a list or values in a dictionary, a shallow copy creates references to the original objects, while a deep copy creates new copies of the original objects. With references, the elements point to the same object, so modifying one of them also affects the other.

First, let's explore what happens when assigning an object to another variable.

When a mutable object, such as a list or a dictionary, is assigned to multiple variables, updating one variable (e.g., changing, adding, or deleting elements) will also affect the other variables.

As demonstrated in the above code example, the is operator shows that the two variables refer to the same object both before and after the value change.

  • Difference between the == and is operators in Python

To create a copy instead of a reference of the same object, use the copy() method or the copy.copy() and copy.deepcopy() functions described below.

For immutable objects like numbers ( int , float ) and strings ( str ), they cannot be updated. When these types of objects are assigned, the two variables refer to the same object initially. However, if one variable is updated to a new value, it becomes a separate object, and the other variable remains the same.

Shallow copy: copy() , copy.copy() , etc.

The copy() method is provided for lists, dictionaries, etc. The copy() method makes a shallow copy.

A shallow copy creates a new object that contains references to the elements found in the original object. For example, in the case of a list, the copied list is a new object, but its elements are references to the same objects in the original list.

Therefore, if the elements are mutable, updating one also affects the other. However, in the case of an immutable element, when its value is changed, it becomes a separate object. The corresponding element in the other list remains unchanged.

The same applies not only to a list of lists as in the example above, but also to a list of dictionaries, a nested dictionary (a dictionary containing other dictionaries as values), and so on.

Slices for mutable sequence types, such as lists, also make shallow copies.

  • How to slice a list, string, tuple in Python

For example, applying the slice [:] that specifies all elements makes a shallow copy of the whole list.

Before Python 3.3 introduced the copy() method for lists, the [:] notation was commonly used to create a shallow copy. For new code, it is generally recommended to use the copy() method to make your intentions clearer.

A slice of a part of the sequence also creates a shallow copy.

If you need to make a deep copy, you can apply the copy.deepcopy() function to the slice.

You can make a shallow copy of a list or dictionary by passing the original list or dictionary to list() or dict() .

You can also make a shallow copy with the copy() function from the copy module.

Use copy.copy() when you need to create a shallow copy of an object that does not provide a copy() method.

To make a deep copy, use the deepcopy() function from the copy module.

In a deep copy, actual copies of the objects are inserted instead of their references. As a result, changes to one object do not affect the other.

Here's an example of applying the deepcopy() function to a slice:

Related Categories

Related articles.

  • NumPy: Replace NaN (np.nan) using np.nan_to_num() and np.isnan()
  • Generate gradient image with Python, NumPy
  • Filter (extract/remove) items of a list with filter() in Python
  • Method chaining across multiple lines in Python
  • Draw circle, rectangle, line, etc. with Python, Pillow
  • Python, Pillow: Flip image
  • pandas: Apply functions to values, rows, columns with map(), apply()
  • Use enumerate() and zip() together in Python
  • How to use range() in Python
  • Save frames from video files as still images with OpenCV in Python
  • pandas: Sort DataFrame/Series with sort_values(), sort_index()
  • Reverse a list, string, tuple in Python (reverse, reversed)
  • Convert a string to a number (int, float) in Python
  • Copy a file/directory in Python (shutil.copy, shutil.copytree)
  • Remove an item from a dictionary in Python (clear, pop, popitem, del)

Learn Python practically and Get Certified .

Popular Tutorials

Popular examples, reference materials, learn python interactively, python introduction.

  • Get Started With Python
  • Your First Python Program
  • Python Comments

Python Fundamentals

  • Python Variables and Literals
  • Python Type Conversion
  • Python Basic Input and Output
  • Python Operators

Python Flow Control

  • Python if...else Statement
  • Python for Loop
  • Python while Loop
  • Python break and continue
  • Python pass Statement

Python Data types

  • Python Numbers, Type Conversion and Mathematics
  • Python List
  • Python Tuple
  • Python Sets
  • Python Dictionary
  • Python Functions
  • Python Function Arguments
  • Python Variable Scope
  • Python Global Keyword
  • Python Recursion
  • Python Modules
  • Python Package
  • Python Main function

Python Files

  • Python Directory and Files Management
  • Python CSV: Read and Write CSV files
  • Reading CSV files in Python
  • Writing CSV files in Python
  • Python Exception Handling
  • Python Exceptions
  • Python Custom Exceptions

Python Object & Class

  • Python Objects and Classes
  • Python Inheritance
  • Python Multiple Inheritance
  • Polymorphism in Python
  • Python Operator Overloading

Python Advanced Topics

  • List comprehension
  • Python Lambda/Anonymous Function
  • Python Iterators
  • Python Generators
  • Python Namespace and Scope
  • Python Closures
  • Python Decorators
  • Python @property decorator
  • Python RegEx

Python Date and Time

  • Python datetime
  • Python strftime()
  • Python strptime()
  • How to get current date and time in Python?
  • Python Get Current Time
  • Python timestamp to datetime and vice-versa
  • Python time Module
  • Python sleep()

Additional Topic

  • Precedence and Associativity of Operators in Python
  • Python Keywords and Identifiers
  • Python Asserts
  • Python Json
  • Python *args and **kwargs

Python Tutorials

Python List copy()

Python Dictionary copy()

Python Set copy()

Python List clear()

  • Python Set union()

Python Shallow Copy and Deep Copy

Copy an object in python.

In Python, we use = operator to create a copy of an object. You may think that this creates a new object; it doesn't. It only creates a new variable that shares the reference of the original object.

Let's take an example where we create a list named old_list and pass an object reference to new_list using = operator.

Example 1: Copy using = operator

When we run above program, the output will be:

As you can see from the output both variables old_list and new_list shares the same id i.e 140673303268168 .

So, if you want to modify any values in new_list or old_list , the change is visible in both.

Essentially, sometimes you may want to have the original values unchanged and only modify the new values or vice versa. In Python, there are two ways to create copies:

  • Shallow Copy

To make these copy work, we use the copy module.

  • Copy Module

We use the copy module of Python for shallow and deep copy operations. Suppose, you need to copy the compound list say x . For example:

Here, the copy() return a shallow copy of x . Similarly, deepcopy() return a deep copy of x .

A shallow copy creates a new object which stores the reference of the original elements.

So, a shallow copy doesn't create a copy of nested objects, instead it just copies the reference of nested objects. This means, a copy process does not recurse or create copies of nested objects itself.

Example 2: Create a copy using shallow copy

When we run the program , the output will be:

In above program, we created a nested list and then shallow copy it using copy() method.

This means it will create new and independent object with same content. To verify this, we print the both old_list and new_list .

To confirm that new_list is different from old_list , we try to add new nested object to original and check it.

Example 3: Adding [4, 4, 4] to old_list, using shallow copy

When we run the program, it will output:

In the above program, we created a shallow copy of old_list . The new_list contains references to original nested objects stored in old_list . Then we add the new list i.e [4, 4, 4] into old_list . This new sublist was not copied in new_list .

However, when you change any nested objects in old_list , the changes appear in new_list .

Example 4: Adding new nested object using Shallow copy

In the above program, we made changes to old_list i.e old_list[1][1] = 'AA' . Both sublists of old_list and new_list at index [1][1] were modified. This is because, both lists share the reference of same nested objects.

A deep copy creates a new object and recursively adds the copies of nested objects present in the original elements.

Let’s continue with example 2. However, we are going to create deep copy using deepcopy() function present in copy module. The deep copy creates independent copy of original object and all its nested objects.

Example 5: Copying a list using deepcopy()

In the above program, we use deepcopy() function to create copy which looks similar.

However, if you make changes to any nested objects in original object old_list , you’ll see no changes to the copy new_list .

Example 6: Adding a new nested object in the list using Deep copy

In the above program, when we assign a new value to old_list , we can see only the old_list is modified. This means, both the old_list and the new_list are independent. This is because the old_list was recursively copied, which is true for all its nested objects.

Table of Contents

  • Copy an Object in Python

Sorry about that.

Related Tutorials

Python Library

Python Copy Module

Copy Module is a set of functions that are related to copying different elements of a list, objects, arrays, etc. It can be used to create shallow copies as well as deep copies.

From the Python 3 documentation

Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other. This module provides generic shallow and deep copy operations.

Shallow copy operations

Shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.

copy.copy(x) Return a shallow copy of x.

Without importing copy module you can’t use it

Deep copy operations.

A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

copy.deepcopy(x[, memo]) Return a deep copy of x.

Subscribe to pythoncheatsheet.org

Join 10.900+ Python developers in a two times a month and bullshit free publication , full of interesting, relevant links.

Pass-by-value, reference, and assignment | Pydon't 🐍

When you call a function in Python and give it some arguments... Are they passed by value? No! By reference? No! They're passed by assignment.

Python snippet containing the code `x is y`.

(If you are new here and have no idea what a Pydon't is, you may want to read the Pydon't Manifesto .)

Introduction

Many traditional programming languages employ either one of two models when passing arguments to functions:

  • some languages use the pass-by-value model; and
  • most of the others use the pass-by-reference model.

Having said that, it is important to know the model that Python uses, because that influences the way your code behaves.

In this Pydon't, you will:

  • see that Python doesn't use the pass-by-value nor the pass-by-reference models;
  • understand that Python uses a pass-by-assignment model;
  • learn about the built-in function id ;
  • create a better understanding for the Python object model;
  • realise that every object has 3 very important properties that define it;
  • understand the difference between mutable and immutable objects;
  • learn the difference between shallow and deep copies; and
  • learn how to use the module copy to do both types of object copies.

You can now get your free copy of the ebook “Pydon'ts – Write elegant Python code” on Gumroad .

Is Python pass-by-value?

In the pass-by-value model, when you call a function with a set of arguments, the data is copied into the function. This means that you can modify the arguments however you please and that you won't be able to alter the state of the program outside the function. This is not what Python does, Python does not use the pass-by-value model.

Looking at the snippet of code that follows, it might look like Python uses pass-by-value:

This looks like the pass-by-value model because we gave it a 3, changed it to a 4, and the change wasn't reflected on the outside ( a is still 3).

But, in fact, Python is not copying the data into the function.

To prove this, I'll show you a different function:

As we can see, the list l , that was defined outside of the function, changed after calling the function clearly_not_pass_by_value . Hence, Python does not use a pass-by-value model.

Is Python pass-by-reference?

In a true pass-by-reference model, the called function gets access to the variables of the callee! Sometimes, it can look like that's what Python does, but Python does not use the pass-by-reference model.

I'll do my best to explain why that's not what Python does:

If Python used a pass-by-reference model, the function would've managed to completely change the value of l outside the function, but that's not what happened, as we can see.

Let me show you an actual pass-by-reference situation.

Here's some Pascal code:

Look at the last lines of that code:

  • we assign 2 to x with x := 2 ;
  • we print x ;
  • we call foo with x as argument; and
  • we print x again.

What's the output of this program?

I imagine that most of you won't have a Pascal interpreter lying around, so you can just go to tio.run and run this code online

If you run this, you'll see that the output is

which can be rather surprising, if the majority of your programming experience is in Python!

The procedure foo effectively received the variable x and changed the value that it contained. After foo was done, the variable x (that lives outside foo ) had a different value. You can't do anything like this in Python.

Python object model

To really understand the way Python behaves when calling functions, it's best if we first understand what Python objects are, and how to characterise them.

The three characteristics of objects

In Python, everything is an object, and each object is characterised by three things:

  • its identity (an integer that uniquely identifies the object, much like social security numbers identify people);
  • a type (that identifies the operations you can do with your object); and
  • the object's content.

Here is an object and its three characteristics:

As we can see above, id is the built-in function you use to query the identity of an object, and type is the built-in function you use to query the type of an object.

(Im)mutability

The (im)mutability of an object depends on its type. In other words, (im)mutability is a characteristic of types, not of specific objects!

But what exactly does it mean for an object to be mutable? Or for an object to be immutable?

Recall that an object is characterised by its identity, its type, and its contents. A type is mutable if you can change the contents of its objects without changing its identity and its type.

Lists are a great example of a mutable data type. Why? Because lists are containers : you can put things inside lists and you can remove stuff from inside those same lists.

Below, you can see how the contents of the list obj change as we make method calls, but the identity of the list remains the same:

However, when dealing with immutable objects, it's a completely different story. If we check an English dictionary, this is what we get for the definition of “immutable”:

adjective: immutable – unchanging over time or unable to be changed.

Immutable objects' contents never change. Take a string as an example:

Strings are a good example for this discussion because, sometimes, they can look mutable. But they are not!

A very good indicator that an object is immutable is when all its methods return something. This is unlike list's .append method, for example! If you use .append on a list, you get no return value. On the other hand, whatever method you use on a string, the result is returned to you:

Notice how obj wasn't updated automatically to "HELLO, WORLD!" . Instead, the new string was created and returned to you.

Another great hint at the fact that strings are immutable is that you cannot assign to its indices:

This shows that, when a string is created, it remains the same. It can be used to build other strings, but the string itself always. stays. unchanged.

As a reference, int , float , bool , str , tuple , and complex are the most common types of immutable objects; list , set , and dict are the most common types of mutable objects.

Variable names as labels

Another important thing to understand is that a variable name has very little to do with the object itself.

In fact, the name obj was just a label that I decided to attach to the object that has identity 2698212637504, has the list type, and contents 1, 2, 3.

Just like I attached the label obj to that object, I can attach many more names to it:

Again, these names are just labels. Labels that I decided to stick to the same object. How can we know it's the same object? Well, all their “social security numbers” (the ids) match, so they must be the same object:

Therefore, we conclude that foo , bar , baz , and obj , are variable names that all refer to the same object.

The operator is

This is exactly what the operator is does: it checks if the two objects are the same .

For two objects to be the same, they must have the same identity:

It is not enough to have the same type and contents! We can create a new list with contents [1, 2, 3] and that will not be the same object as obj :

Think of it in terms of perfect twins. When two siblings are perfect twins, they look identical. However, they are different people!

Just as a side note, but an important one, you should be aware of the operator is not .

Generally speaking, when you want to negate a condition, you put a not in front of it:

So, if you wanted to check if two variables point to different objects, you could be tempted to write

However, Python has the operator is not , which is much more similar to a proper English sentence, which I think is really cool!

Therefore, the example above should actually be written

Python does a similar thing for the in operator, providing a not in operator as well... How cool is that?!

Assignment as nicknaming

If we keep pushing this metaphor forward, assigning variables is just like giving a new nickname to someone.

My friends from middle school call me “Rojer”. My friends from college call me “Girão”. People I am not close to call me by my first name – “Rodrigo”. However, regardless of what they call me, I am still me , right?

If one day I decide to change my haircut, everyone will see the new haircut, regardless of what they call me!

In a similar fashion, if I modify the contents of an object, I can use whatever nickname I prefer to see that those changes happened. For example, we can change the middle element of the list we have been playing around with:

We used the nickname foo to modify the middle element, but that change is visible from all other nicknames as well.

Because they all pointed at the same list object.

Python is pass-by-assignment

Having laid out all of this, we are now ready to understand how Python passes arguments to functions.

When we call a function, each of the parameters of the function is assigned to the object they were passed in. In essence, each parameter now becomes a new nickname to the objects that were given in.

Immutable arguments

If we pass in immutable arguments, then we have no way of modifying the arguments themselves. After all, that's what immutable means: “doesn't change”.

That is why it can look like Python uses the pass-by-value model. Because the only way in which we can have the parameter hold something else is by assigning it to a completely different thing. When we do that, we are reusing the same nickname for a different object:

In the example above, when we call foo with the argument 5 , it's as if we were doing bar = 5 at the beginning of the function.

Immediately after that, we have bar = 3 . This means “take the nickname "bar" and point it at the integer 3 ”. Python doesn't care that bar , as a nickname (as a variable name) had already been used. It is now pointing at that 3 !

Mutable arguments

On the other hand, mutable arguments can be changed. We can modify their internal contents. A prime example of a mutable object is a list: its elements can change (and so can its length).

That is why it can look like Python uses a pass-by-reference model. However, when we change the contents of an object, we didn't change the identity of the object itself. Similarly, when you change your haircut or your clothes, your social security number does not change:

Do you understand what I'm trying to say? If not, drop a comment below and I'll try to help.

Beware when calling functions

This goes to show you should be careful when defining your functions. If your function expects mutable arguments, you should do one of the two:

  • do not mutate the argument in any way whatsoever; or
  • document explicitly that the argument may be mutated.

Personally, I prefer to go with the first approach: to not mutate the argument; but there are times and places for the second approach.

Sometimes, you do need to take the argument as the basis for some kind of transformation, which would mean you would want to mutate the argument. In those cases, you might think about doing a copy of the argument (discussed in the next section), but making that copy can be resource intensive. In those cases, mutating the argument might be the only sensible choice.

Making copies

Shallow vs deep copies.

“Copying an object” means creating a second object that has a different identity (therefore, is a different object) but that has the same contents. Generally speaking, we copy one object so that we can work with it and mutate it, while also preserving the first object.

When copying objects, there are a couple of nuances that should be discussed.

Copying immutable objects

The first thing that needs to be said is that, for immutable objects, it does not make sense to talk about copies.

“Copies” only make sense for mutable objects. If your object is immutable, and if you want to preserve a reference to it, you can just do a second assignment and work on it:

Or, sometimes, you can just call methods and other functions directly on the original, because the original is not going anywhere:

So, we only need to worry about mutable objects.

Shallow copy

Many mutable objects can contain, themselves, mutable objects. Because of that, two types of copies exist:

  • shallow copies; and
  • deep copies.

The difference lies in what happens to the mutable objects inside the mutable objects.

Lists and dictionaries have a method .copy that returns a shallow copy of the corresponding object.

Let's look at an example with a list:

First, we create a list inside a list, and we copy the outer list. Now, because it is a copy , the copied list isn't the same object as the original outer list:

But if they are not the same object, then we can modify the contents of one of the lists, and the other won't reflect the change:

That's what we saw: we changed the first element of the copy_list , and the outer_list remained unchanged.

Now, we try to modify the contents of sublist , and that's when the fun begins!

When we modify the contents of sublist , both the outer_list and the copy_list reflect those changes...

But wasn't the copy supposed to give me a second list that I could change without affecting the first one? Yes! And that is what happened!

In fact, modifying the contents of sublist doesn't really modify the contents of neither copy_list nor outer_list : after all, the third element of both was pointing at a list object, and it still is! It's the (inner) contents of the object to which we are pointing that changed.

Sometimes, we don't want this to happen: sometimes, we don't want mutable objects to share inner mutable objects.

Common shallow copy techniques

When working with lists, it is common to use slicing to produce a shallow copy of a list:

Using the built-in function for the respective type, on the object itself, also builds shallow copies. This works for lists and dictionaries, and is likely to work for other mutable types.

Here is an example with a list inside a list:

And here is an example with a list inside a dictionary:

When you want to copy an object “thoroughly”, and you don't want the copy to share references to inner objects, you need to do a “deep copy” of your object. You can think of a deep copy as a recursive algorithm.

You copy the elements of the first level and, whenever you find a mutable element on the first level, you recurse down and copy the contents of those elements.

To show this idea, here is a simple recursive implementation of a deep copy for lists that contain other lists:

We can use this function to copy the previous outer_list and see what happens:

As you can see here, modifying the contents of sublist only affected outer_list indirectly; it didn't affect copy_list .

Sadly, the list_deepcopy method I implemented isn't very robust, nor versatile, but the Python Standard Library has got us covered!

The module copy and the method deepcopy

The module copy is exactly what we need. The module provides two useful functions:

  • copy.copy for shallow copies; and
  • copy.deepcopy for deep copies.

And that's it! And, what is more, the method copy.deepcopy is smart enough to handle issues that might arise with circular definitions, for example! That is, when an object contains another that contains the first one: a naïve recursive implementation of a deep copy algorithm would enter an infinite loop!

If you write your own custom objects and you want to specify how shallow and deep copies of those should be made, you only need to implement __copy__ and __deepcopy__ , respectively!

It's a great module, in my opinion.

Examples in code

Now that we have gone deep into the theory – pun intended –, it is time to show you some actual code that plays with these concepts.

Mutable default arguments

Let's start with a Twitter favourite:

Python 🐍 is an incredible language but sometimes appears to have quirks 🤪 For example, one thing that often confuses beginners is why you shouldn't use lists as default values 👇 Here is a thread 👇🧵 that will help you understand this 💯 pic.twitter.com/HVhPjS2PSH — Rodrigo 🐍📝 (@mathsppblog) October 5, 2021

Apparently, it's a bad idea to use mutable objects as default arguments. Here is a snippet showing you why:

The function above appends an element to a list and, if no list is given, appends it to an empty list by default.

Great, let's put this function to good use:

We use it once with 1 , and we get a list with the 1 inside. Then, we use it to append a 1 to another list we had. And finally, we use it to append a 3 to an empty list... Except that's not what happens!

As it turns out, when we define a function, the default arguments are created and stored in a special place:

What this means is that the default argument is always the same object. Therefore, because it is a mutable object, its contents can change over time. That is why, in the code above, __defaults__ shows a list with two items already.

If we redefine the function, then its __defaults__ shows an empty list:

This is why, in general, mutable objects shouldn't be used as default arguments.

The standard practice, in these cases, is to use None and then use Boolean short-circuiting to assign the default value:

With this implementation, the function now works as expected:

is not None

Searching through the Python Standard Library shows that the is not operator is used a bit over 5,000 times. That's a lot.

And, by far and large, that operator is almost always followed by None . In fact, is not None appears 3169 times in the standard library!

x is not None does exactly what it's written: it checks if x is None or not.

Here is a simple example usage of that, from the argparse module to create command line interfaces:

Even without a great deal of context, we can see what is happening: when displaying command help for a given section, we may want to indent it (or not) to show hierarchical dependencies.

If a section's parent is None , then that section has no parent, and there is no need to indent. In other words, if a section's parent is not None , then we want to indent it. Notice how my English matches the code exactly!

Deep copy of the system environment

The method copy.deepcopy is used a couple of times in the standard library, and here I'd like to show an example usage where a dictionary is copied.

The module os provides the attribute environ , similar to a dictionary, that contains the environment variables that are defined.

Here are a couple of examples from my (Windows) machine:

The module http.server provides some classes for basic HTTP servers.

One of those classes, CGIHTTPRequestHandler , implements a HTTP server that can also run CGI scripts and, in its run_cgi method, it needs to set a bunch of environment variables.

These environment variables are set to give the necessary context for the CGI script that is going to be ran. However, we don't want to actually modify the current environment!

So, what we do is create a deep copy of the environment, and then we modify it to our heart's content! After we are done, we tell Python to execute the CGI script, and we provide the altered environment as an argument.

The exact way in which this is done may not be trivial to understand. I, for one, don't think I could explain it to you. But that doesn't mean we can't infer parts of it:

Here is the code:

As we can see, we copied the environment and defined some variables. Finally, we created a new subprocess that gets the modified environment.

Here's the main takeaway of this Pydon't, for you, on a silver platter:

“ Python uses a pass-by-assignment model, and understanding it requires you to realise all objects are characterised by an identity number, their type, and their contents. ”

This Pydon't showed you that:

  • Python doesn't use the pass-by-value model, nor the pass-by-reference one;
  • Python uses a pass-by-assignment model (using “nicknames”);
  • its identity;
  • its type; and
  • its contents.
  • the id function is used to query an object's identifier;
  • the type function is used to query an object's type;
  • the type of an object determines whether it is mutable or immutable;
  • shallow copies copy the reference of nested mutable objects;
  • deep copies perform copies that allow one object, and its inner elements, to be changed without ever affecting the copy;
  • copy.copy and copy.deepcopy can be used to perform shallow/deep copies; and
  • you can implement __copy__ and __deepcopy__ if you want your own objects to be copiable.

If you prefer video content, you can check this YouTube video , which was inspired by this article.

If you liked this Pydon't be sure to leave a reaction below and share this with your friends and fellow Pythonistas. Also, subscribe to the newsletter so you don't miss a single Pydon't!

Become a better Python 🐍 developer 🚀

+35 chapters. +400 pages. Hundreds of examples. Over 30,000 readers!

My book “Pydon'ts” teaches you how to write elegant, expressive, and Pythonic code, to help you become a better developer. >>> Download it here 🐍🚀 .

  • Python 3 Docs, Programming FAQ, “How do I write a function with output parameters (call by reference)?”, https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference [last accessed 04-10-2021];
  • Python 3 Docs, The Python Standard Library, copy , https://docs.python.org/3/library/copy.html [last accessed 05-10-2021];
  • effbot.org, “Call by Object” (via “arquivo.pt”), https://arquivo.pt/wayback/20160516131553/http://effbot.org/zone/call-by-object.htm [last accessed 04-10-2021];
  • effbot.org, “Python Objects” (via “arquivo.pt”), https://arquivo.pt/wayback/20191115002033/http://effbot.org/zone/python-objects.htm [last accessed 04-10-2021];
  • Robert Heaton, “Is Python pass-by-reference or pass-by-value”, https://robertheaton.com/2014/02/09/pythons-pass-by-object-reference-as-explained-by-philip-k-dick/ [last accessed 04-10-2021];
  • StackOverflow question and answers, “How do I pass a variable by reference?”, https://stackoverflow.com/q/986006/2828287 [last accessed 04-10-2021];
  • StackOverflow question and answers, “Passing values in Python [duplicate]”, https://stackoverflow.com/q/534375/2828287 [last accessed 04-10-2021];
  • Twitter thread by @mathsppblog , https://twitter.com/mathsppblog/status/1445148566721335298 [last accessed 20-10-2021];

Previous Post Next Post

Random Article

Stay in the loop, popular tags.

  • 6 April 2024
  • 5 March 2024
  • 2 February 2024
  • 8 January 2024
  • 1 December 2023
  • 22 November 2023
  • 4 October 2023
  • 6 September 2023
  • 7 August 2023
  • 12 July 2023
  • 4 June 2023

+[-->-[>>+>----- -.>>>+.>>..+++[.>] >>>+.

mathspp

  • Python Basics
  • Interview Questions
  • Python Quiz
  • Popular Packages
  • Python Projects
  • Practice Python
  • AI With Python
  • Learn Python3
  • Python Automation
  • Python Web Dev
  • DSA with Python
  • Python OOPs
  • Dictionaries
  • Python List methods
  • Python List append() Method
  • Python List extend() Method
  • Python List index()
  • Python List max() Method
  • Python min() Function
  • How To Find the Length of a List in Python
  • Python List pop() Method
  • Python List remove() Method
  • Python List reverse()
  • Python List count() method

Python List copy() Method

  • Python List clear() Method
  • Python List insert() Method With Examples
  • Python List sort() Method

The list Copy() method makes a new shallow copy of a list.

What is List Copy() Method?

The list Copy() function in Python is used to create a copy of a list. There are two main ways to create a copy of the list Shallow copy and Deep copy. We will discuss the list copy() method in detail below.

The list copy() function is used to create a copy of a list, which can be used to work and it will not affect the values in the original list. This gives freedom to manipulate data without worrying about data loss.

List copy() Method Syntax

list.copy()
  • The copy() method doesn’t take any parameters.

Returns: Returns a shallow copy of a list. 

Note : A shallow copy means any modification in the new list won’t be reflected in the original list. 

How to Create a Simple Copy of a List in Python

Copying and creating a new list can be done using copy() function in Python.

More Examples on List copy() Method

Let us see a few examples of the list copy() method.

Example 1: Simple List Copy

In this example, we are creating a List of Python strings and we are using copy() method to copy the list to another variable.

Example 2: Demonstrating the working of List copy() 

Here we will create a Python list and then create a shallow copy using the copy() function. Then we will append a value to the copied list to check if copying a list using copy() method affects the original list.

Note: A shallow copy means if we modify any of the nested list elements, changes are reflected in both lists as they point to the same reference.

Shallow Copy and Deep Copy

A deep copy is a copy of a list, where we add an element in any of the lists, only that list is modified. 

In list copy() method, changes made to the copied list are not reflected in the original list. The changes made to one list are not reflected on other lists except for in nested elements (like a list within a list).

We can use the copy.deepcopy() from the copy module to avoid this problem.

  • Using copy.deepcopy()
  • Using copy.copy()
  • Using list.copy()
  • Using slicing
To gain a deeper understanding, Refer to this article on Deep Copy vs Shallow Copy . 

Demonstrating Techniques of Shallow and Deep copy  

Here we will create a list and then create a shallow copy using the assignment operator , list copy() method, and copy.copy() method of the Python copy module.

We also create a deep copy using deepcopy() in Python. Then we will make changes to the original list and see if the other lists are affected or not.

Copy List Using Slicing

Here we are copying the list using the list slicing method [:] and we are appending the ‘a’ to the new_list. After printing we can see the newly appended character ‘a’ is not appended to the old list.

We discussed the definition, syntax and examples of list copy() method. copy() function is very useful when working with sensitive data and you can’t risk mistakes.

We also briefly talked about shallow vs deep copy. Hope this helped you in understanding copy() function in Python.

Read Other Python List Methods

More articles on to list copy:

  • Python | Cloning or Copying a list
  • copy in Python (Deep Copy and Shallow Copy)
  • Python | How to copy a nested list

Please Login to comment...

Similar reads.

author

  • python-list
  • python-list-functions

advertisewithusBannerImg

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

Installation of Jupyter Notebook

Hi, I am new to Python. I hve trying to open jupyter notebook on the laptop since 3 weeks ago, i have been unable. the error message i do see is Error processing line 7 of C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\site-packages\pywin32.pth: Kindly assist as it slowing my Data Science classes down.

Are you able to copy and paste the text of the error message?

If you can, please copy and paste everything that is shown as an error message, and show it like code, following the instructions in the pinned thread . Otherwise, please show a screenshot. It does not make any sense right now that what you have shown is complete (it should not end with : , that makes it look like there should be more after it).

Please also clearly explain the steps that you take in order to try to “open jupyter notebook on the laptop”.

I downloaded python 3.12.2-amd64 to windom 10 laptop

When i want to check if pip is install and with latest version through cmd.

C:\Users\User>pip3 install --upgrade pip

It display this

C:\Users\User>pip3 install --upgrade pip Error processing line 7 of C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\site-packages\pywin32.pth:

Traceback (most recent call last): File “”, line 195, in addpackage File “”, line 1, in SyntaxError: source code string cannot contain null bytes

Remainder of file ignored Requirement already satisfied: pip in c:\users\user\appdata\local\programs\python\python312\lib\site-packages (24.0)

I tried to check if Jupyter install

C:\Users\User>jupyter

It brought the following

C:\Users\User>jupyter Error processing line 7 of C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\site-packages\pywin32.pth:

Remainder of file ignored usage: jupyter [-h] [–version] [–config-dir] [–data-dir] [–runtime-dir] [–paths] [–json] [–debug] [subcommand]

Jupyter: Interactive Computing

positional arguments: subcommand the subcommand to launch

options: -h, --help show this help message and exit –version show the versions of core jupyter packages and exit –config-dir show Jupyter config dir –data-dir show Jupyter data dir –runtime-dir show Jupyter runtime dir –paths show all Jupyter paths. Add --json for machine-readable format. –json output paths as machine-readable json –debug output debug information about paths

Available subcommands: console dejavu events execute kernel kernelspec lab labextension labhub migrate nbconvert notebook qtconsole run server troubleshoot trust

Please specify a subcommand or one of the optional arguments.

I tried to open jupyter

C:\Users\User>jupyter notebook

I was expecting to see it in a browser but it display the following in the CMD command

Error processing line 7 of C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\site-packages\pywin32.pth:

Remainder of file ignored Error processing line 7 of C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\site-packages\pywin32.pth:

Remainder of file ignored Traceback (most recent call last): File “”, line 198, in run_module_as_main File “”, line 88, in run_code File "C:\Users\User\AppData\Local\Programs\Python\Python312\Scripts\jupyter-notebook.EXE_ main .py", line 4, in File “C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\site-packages\notebook\app.py”, line 9, in from jupyter_client.utils import ensure_async # type:ignore[attr-defined] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\site-packages\jupyter_client_ init .py", line 3, in from .asynchronous import AsyncKernelClient File “C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\site-packages\jupyter_client\asynchronous_ init _.py”, line 1, in from .client import AsyncKernelClient # noqa ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File “C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\site-packages\jupyter_client\asynchronous\client.py”, line 8, in import zmq.asyncio File “C:\Users\User\AppData\Local\Programs\Python\Python312\Lib\site-packages\zmq_ init _.py”, line 141, in from zmq import sugar SyntaxError: source code string cannot contain null bytes

Kindly assist

Related topics.

IMAGES

  1. Copy a File in Python

    does python assignment copy

  2. Python Tutorials

    does python assignment copy

  3. Python Copy File (Examples)

    does python assignment copy

  4. Python For Beginners

    does python assignment copy

  5. Python: Assignment vs Shallow Copy vs Deep Copy

    does python assignment copy

  6. Tips on How to Write Python Assignment by My Essay Mate

    does python assignment copy

VIDEO

  1. Python Coding

  2. How to use assignment operators in #python

  3. Python Basics

  4. Python

  5. Python Assignment Operator #coding #assignmentoperators #phython

  6. Python Assignment Operators And Comparison Operators

COMMENTS

  1. Does Python make a copy of objects on assignment?

    When you assign dict_a = dict_b, you are really copying a memory address (or pointer, if you will) from dict_b to dict_a. There is still one instance of that dictionary. To get the desired behavior, use either the dict.copy method, or use copy.deepcopy if your dict may have nested dicts or other nested objects. >>> a = {1:2}

  2. copy

    Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other. This module provides generic shallow and deep copy operations (explained below). Interface summary:

  3. Python: Assignment vs Shallow Copy vs Deep Copy

    For compound objects (e.g. a list of lists): Use assignment =if you want the new changes to affect the original list. Use deepcopy if you don'twant the new changes to affect the original list ...

  4. Python : When is a variable passed by reference and when by value

    33. Everything in Python is passed and assigned by value, in the same way that everything is passed and assigned by value in Java. Every value in Python is a reference (pointer) to an object. Objects cannot be values. Assignment always copies the value (which is a pointer); two such pointers can thus point to the same object.

  5. Shallow vs Deep Copying of Python Objects

    A shallow copy means constructing a new collection object and then populating it with references to the child objects found in the original. In essence, a shallow copy is only one level deep. The copying process does not recurse and therefore won't create copies of the child objects themselves. A deep copy makes the copying process recursive.

  6. copy in Python (Deep Copy and Shallow Copy)

    In Python, Assignment statements do not copy objects, they create bindings between a target and an object.When we use the = operator, It only creates a new variable that shares the reference of the original object. In order to create "real copies" or "clones" of these objects, we can use the copy module in Python.. Syntax of Python Deepcopy

  7. Assignment, Shallow Copy, Or Deep Copy?

    Variable Assignment. It says in the Python documentation that "Assignment statements in Python do not copy objects, they create bindings between a target and an object." That means when we create a variable by assignment, the new variable refers to the same object as the original variable does —

  8. Python: Deep and Shallow Copy Object

    Shallow Copy an Object in Python. When we use assignment statements (=) in Python to create copies of compound objects, such as lists or class instances or basically any objects that contain some other objects, Python does not clone the object itself. Instead, it simply binds the reference to the targeted object.

  9. Shallow and deep copy in Python: copy(), deepcopy()

    In Python, you can make a shallow and deep copy using the copy() and deepcopy() functions from the copy module. A shallow copy can also be made with the copy() method of lists, dictionaries, and so on. The following is a summary of the differences between assignment to another variable, shallow copy, and deep copy.

  10. Python: Deep vs Shallow copy. As we know python assignment statements

    As we know python assignment statements do not copy objects, they simply create bindings between a target and an object. Sometimes we have a list (collection) of mutable items and need to create its copies so that change one copy without impacting the others. In Python, there are two ways to create copies : Deep copy; Shallow copy

  11. Python Shallow Copy and Deep Copy (With Examples)

    Copy Module. We use the copy module of Python for shallow and deep copy operations. Suppose, you need to copy the compound list say x. For example: import copy. copy.copy(x) copy.deepcopy(x) Here, the copy() return a shallow copy of x. Similarly, deepcopy() return a deep copy of x.

  12. Shallow Copy vs Deep Copy vs Assignment in Python

    Assignment Operation in python usually won't create copies. It will create references to the existing object. If we try to modify the value of y=10, only value of y is changed. x remains the ...

  13. Python Copy Module

    Python Copy Module. Copy Module is a set of functions that are related to copying different elements of a list, objects, arrays, etc. It can be used to create shallow copies as well as deep copies. From the Python 3 documentation. Assignment statements in Python do not copy objects, they create bindings between a target and an object. For ...

  14. Python's Assignment Operator: Write Robust Assignments

    Here, variable represents a generic Python variable, while expression represents any Python object that you can provide as a concrete value—also known as a literal—or an expression that evaluates to a value. To execute an assignment statement like the above, Python runs the following steps: Evaluate the right-hand expression to produce a concrete value or object.

  15. Python: Deep and Shallow Copy. In Python, the = (assignment) operation

    In Python, the = (assignment) operation does not pass by reference. Instead, it binds a new name to the same object. ... So, if we want to create a copy of a list without affecting the original list, we can use the copy module in Python. Shallow Copy. A shallow copy of a list copies the top-level elements but not the nested elements.

  16. Pass by Reference in Python: Background and Best Practices

    Understanding Assignment in Python. Python's language reference for assignment statements provides the following details: If the assignment target is an identifier, or variable name, then this name is bound to the object. For example, in x = 2, x is the name and 2 is the object. If the name is already bound to a separate object, then it's ...

  17. Pass-by-value, reference, and assignment

    Python doesn't use the pass-by-value model, nor the pass-by-reference one; Python uses a pass-by-assignment model (using "nicknames"); each object is characterised by. its identity; its type; and. its contents. the id function is used to query an object's identifier; the type function is used to query an object's type;

  18. python

    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. ... 10.16 sec (101.6 µs/itn) - pure Python Copy() method copying classes with deepcopy; 1.488 sec (14.88 µs/itn) - pure Python Copy() method not copying classes (only dicts/lists/tuples)

  19. Python List copy() Method

    Here we will create a list and then create a shallow copy using the assignment operator, list copy() method, and copy.copy() method of the Python copy module. We also create a deep copy using deepcopy() in Python. Then we will make changes to the original list and see if the other lists are affected or not.

  20. Installation of Jupyter Notebook

    Please HELP! Issue downloading as Python file from Jupyter Notebook - the py script is blank?

  21. python

    This copies the values from A into an existing array B. The two arrays must have the same shape for this to work. B[:] = A[:] does the same thing (but B = A[:] would do something more like 1). numpy.copy(B, A) This is not legal syntax. You probably meant B = numpy.copy(A). This is almost the same as 2, but it creates a new array, rather than ...

  22. Python Variable Scope (passing by reference or copy?)

    21. Long story short: Python uses pass-by-value, but the things that are passed by value are references. The actual objects have 0 to infinity references pointing at them, and for purposes of mutating that object, it doesn't matter who you are and how you got a reference to the object. Going through your example step by step: