How to Copy List of Lists in Python (Shallow vs Deep)?

Python is the most popular programming language in the world. The most important data structure in the most important programming language is the list data structure.

In this tutorial, you’ll learn how to copy a list of lists. But be careful—simply copying your list may not do what you expected it to do. Let’s dive into an important distinction: shallow vs deep copies.

Short answer:

  • To create a shallow copy of a list of lists, use the list.copy() method that creates a new outer list with copied references to the same inner lists.
  • To create a deep copy with copied inner lists, import the copy library and call copy.deepcopy(list) to copy both the inner and outer lists.

The following interactive code widget gives you a quick overview. A detailed discussion follows after that. Can you figure out why the output is different for the two different methods to copy a list?

Method 1: Python List Copy Shallow

Before you can truly understand the copy() method in Python, you must understand the concept of a “shallow copy”.

In object-oriented languages such as Python, everything is an object. The list is an object and the elements in the list are objects, too. A shallow copy of the list creates a new list object—the copy—but it doesn’t create new list elements but simply copies the references to these objects.

You can see that the list below is only a shallow copy pointing to the same elements as the original list.

In Python, the list.copy() method only produces a shallow copy which has much faster runtime complexity.

Here’s an example showing exact this scenario:

lst = [[1, 0], [2, 2], [0, 0]]
lst_copy = lst.copy()
lst_copy[2].append(42)
print(lst[2])

Changing the third list element of the copied list impacts the third list element of the original list. Thus, the output is:

[0, 0, 42]

You can see a live execution visualization in the following great tool to visualize the memory usage of this Python snippet at every stage of the execution. Just click “Next” to see how the memory unfolds:

Hint: If you copy a list of lists using the list.copy() method, be aware that any change you’re performing on a list in the copied list of lists is visible in the original list.

If you aren’t okay with that, check out the following section about deep copies of Python lists:

Method 2: Python List Copy Deep

Having understood the concept of a shallow copy, it’s now easy to understand the concept of a deep copy. A shallow copy only copies the references of the list elements. A deep copy copies the list elements themselves which can lead to a highly recursive behavior because the list elements may be lists themselves that need to be copied deeply and so on.

Here’s a simple deep copy of the same list as shown previously:

In contrast to the shallow copy, the list [1, 2] is copied separately for the deep copy list. If one changes this nested list in the original list, the change would not be visible at the deep copy. (Because the nested list of the deep copy list is an independent object in memory.)

Note that in a deep copy, the string object must not be copied. Why? Because strings are immutable so you cannot change them (and, thus, there will be no dirty “side effects” seen by other copies of the list pointing to the same object in memory).

To get a deep copy in Python, import the copy module and use the deepcopy() method:

import copy
lst = [[1, 0], [2, 2], [0, 0]]
lst_copy = copy.deepcopy(lst)
lst_copy[2].append(42)
print(lst[2])
# [0, 0]

Again, visualize the execution flow of the following code snippet right here in your browser by clicking “Next”:

How to Copy a Python List (Alternatives)?

Say, you want to copy the list. What options are there?

MethodDescription
list.copy()Returns a shallow copy of the list.
import copy
copy.deepcopy(list)
Import the copy module and uses its method to create a deep copy of list.
list[:]Use slicing with default indices to create a shallow copy of the list.
list(x)use the built-in list constructor list(...) to create a shallow copy of the list x.
[el for el in lst]Use list comprehension to create a shallow copy of the original list lst.

Slicing belongs to the fastest methods (very dirty benchmark here). If you need to refresh your Python slicing skills, here’s a tutorial on the Finxter blog:

Related Articles:

Where to Go From Here?

Enough theory. Let’s get some practice!

Coders get paid six figures and more because they can solve problems more effectively using machine intelligence and automation.

To become more successful in coding, solve more real problems for real people. That’s how you polish the skills you really need in practice. After all, what’s the use of learning theory that nobody ever needs?

You build high-value coding skills by working on practical coding projects!

Do you want to stop learning with toy projects and focus on practical code projects that earn you money and solve real problems for people?

🚀 If your answer is YES!, consider becoming a Python freelance developer! It’s the best way of approaching the task of improving your Python skills—even if you are a complete beginner.

If you just want to learn about the freelancing opportunity, feel free to watch my free webinar “How to Build Your High-Income Skill Python” and learn how I grew my coding business online and how you can, too—from the comfort of your own home.

Join the free webinar now!