Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Sunshine And March Vibes (2025 Wallpapers Edition)

      May 13, 2025

      The Case For Minimal WordPress Setups: A Contrarian View On Theme Frameworks

      May 13, 2025

      How To Fix Largest Contentful Paint Issues With Subpart Analysis

      May 13, 2025

      How To Prevent WordPress SQL Injection Attacks

      May 13, 2025

      This $4 Steam Deck game includes the most-played classics from my childhood — and it will save you paper

      May 13, 2025

      Microsoft shares rare look at radical Windows 11 Start menu designs it explored before settling on the least interesting one of the bunch

      May 13, 2025

      NVIDIA’s new GPU driver adds DOOM: The Dark Ages support and improves DLSS in Microsoft Flight Simulator 2024

      May 13, 2025

      How to install and use Ollama to run AI LLMs on your Windows 11 PC

      May 13, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Community News: Latest PECL Releases (05.13.2025)

      May 13, 2025
      Recent

      Community News: Latest PECL Releases (05.13.2025)

      May 13, 2025

      How We Use Epic Branches. Without Breaking Our Flow.

      May 13, 2025

      I think the ergonomics of generators is growing on me.

      May 13, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      This $4 Steam Deck game includes the most-played classics from my childhood — and it will save you paper

      May 13, 2025
      Recent

      This $4 Steam Deck game includes the most-played classics from my childhood — and it will save you paper

      May 13, 2025

      Microsoft shares rare look at radical Windows 11 Start menu designs it explored before settling on the least interesting one of the bunch

      May 13, 2025

      NVIDIA’s new GPU driver adds DOOM: The Dark Ages support and improves DLSS in Microsoft Flight Simulator 2024

      May 13, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»How to Copy Objects in Python

    How to Copy Objects in Python

    April 17, 2025

    In this tutorial, you’ll learn about copying objects in Python using the copy module. We’ll cover how to use the copy module and when to use its copy() function and deepcopy() function, depending on the scenario. You’ll also learn which way of copying is suitable for mutable and immutable objects.

    By the end of this tutorial, you’ll understand:

    • What is the copy module?

    • The difference between copying and referencing.

    • The difference between a deep copy and a shallow copy.

    • How to actually shallow copy and deep copy objects in Python.

    • The difference in referencing for immutable objects and mutable objects.

    Prerequisites

    To get the most out of this tutorial, you need to have a basic understanding of the following:

    1. Fundamental knowledge of programming and its terminology (such as objects, memory addresses, and so on)

    2. Basic knowledge of Python programming, especially (for this tutorial),

      • Function id(): Outputs the memory address of the object passed as argument.

      • Data structures: Dictionaries and Lists.

      • Modules: importing and using them in the program. Basic understanding of methods and functions.

    Table of Contents:

    1. What is the Copy Module in Python?

      • Why Can’t We Just Use the Assignment Operator?
    2. How to Properly Copy Objects in Python

    3. More About Copying Objects in Python

    4. Summary

    What is the copy Module?

    The copy module is an in-built module in Python which is primarily used for copying objects in Python. it lets you make changes to a mutable object and save it as a different copy in memory. So basically, it makes a copy of the original object and stores it in a different memory location.

    Why can’t we just use the assignment operator (=) for copying objects?

    If we use the assignment operator for the purpose of copying objects, it doesn’t actually copy the object – rather, it creates a binding between the object and the identifier. This means that if the original object points at memory location x, then the identifier in which we attempted to copy the object by using the = operator will also point at the same memory location, that is location x.

    Now, this may create problems while manipulating various aspects of the data, as the changes that we make in the object will reflect in its binding as well.

    Before jumping into the code, let’s first look at the difference between copying and referencing:

    • Copying: Creating a copy refers to replicating the target object and storing it separately into the memory, making it an independent object with same data.

    • Referencing: Referencing an object refers to pointing to the same memory address where the target object is stored. The referenced object is just another name (which we call as an ‘alias’ in programming) to call out the original object.

    Let’s understand this with an example:

    # creating a dictionary object.
    d1 = {
        'A' : 1,
        'B' : 2,
        'C' : 3
    }
    
    # using assignment operator to copy d1 in d2.
    d2=d1
    
    # printing both the dictionaries.
    print(f'd1 = {d1} nd2 = {d2}')
    

    Output:

    d1 = {‘A’: 1, ‘B’: 2, ‘C’: 3}

    d2 = {‘A’: 1, ‘B’: 2, ‘C’: 3}

    From above example, it may seem that the dictionary got copied in variable d2 – but in reality, it’s just pointing to the object stored in variable d1. In this case, variable d2 is just an alias or reference to the same object d1. We can prove this as follows:

    d1 = {
        'A' : 1,
        'B' : 2,
        'C' : 3
    }
    
    d2=d1
    
    d1['D'] = 4 # added a key-value pair in d1
    
    print(f'd1 = {d1} nd2 = {d2}')
    

    Output:

    d1 = {‘A’: 1, ‘B’: 2, ‘C’: 3, ‘D’: 4}

    d2 = {‘A’: 1, ‘B’: 2, ‘C’: 3, ‘D’: 4}

    Now, in the above code, we appended a key-value pair in dictionary d1 only – but the change is seen in dictionary d2, too. From this, it is evident that both the identifiers were referencing the same object.

    From this we understand that, assignment operator = can be used for referencing the objects and we cannot use it for copying objects in true sense.

    How to Properly Copy Objects in Python

    Since you now understand the difference between copying and referencing, let’s see how you can actually copy objects in Python. For this, we will make use of the copy module (mentioned earlier).

    Now, before using this module, you should understand the difference between a deep copy and a shallow copy.

    • Deep copy: While working with compound objects (also known as container objects or composite objects), deep copying means to create a copy of the inner objects as well as the outer object.

    • Shallow copy: While working with compound objects, shallow copying refers to copying only the outer object and referencing the inner objects.

    Note: Compound objects are objects that contain other objects inside them.

    Let’s better understand the difference between deep and shallow copies by actually implementing them in a program:

    import copy # importing copy module
    
    # creating a composite object
    categories = {
        'Fruits' : ['Apple', 'Banana', 'Mango'],
        'Flowers' : ['Rose', 'Sunflower', 'Tulip'],
    }
    
    # copying the object by using the copy() function of the copy module
    categories_copy = copy.copy(categories)
    
    print(f'Categories = {categories}nCategories (Copied) = {categories_copy}')
    

    Output:

    Categories = {‘Fruits’: [‘Apple’, ‘Banana’, ‘Mango’], ‘Flowers’: [‘Rose’, ‘Sunflower’, ‘Tulip’]}

    Categories (Copied) = {‘Fruits’: [‘Apple’, ‘Banana’, ‘Mango’], ‘Flowers’: [‘Rose’, ‘Sunflower’, ‘Tulip’]}

    In the above example, we made a composite object called categories that contains lists as the inner objects. Then, we used the copy() function of the copy module to shallow copy the original object. Also, since the copy module is in-built, there is no need to install it manually! Now, both the objects appear similar.

    Next, let’s modify the original object to see if the object is really copied or it is just referenced:

    import copy
    
    categories = {
        'Fruits' : ['Apple', 'Banana', 'Mango'],
        'Flowers' : ['Rose', 'Sunflower', 'Tulip'],
    }
    
    categories_copy = copy.copy(categories)
    
    # added a key-value pair in the original dictionary.
    categories['Color'] = ['Red', 'Yellow', 'Blue']
    
    print(f'Categories = {categories}nCategories (Copied) = {categories_copy}')
    

    Output:

    Categories = {‘Fruits’: [‘Apple’, ‘Banana’, ‘Mango’], ‘Flowers’: [‘Rose’, ‘Sunflower’, ‘Tulip’], ‘Color’: [‘Red’, ‘Yellow’, ‘Blue’]}

    Categories (Copied) = {‘Fruits’: [‘Apple’, ‘Banana’, ‘Mango’], ‘Flowers’: [‘Rose’, ‘Sunflower’, ‘Tulip’]}

    Here, we can see that even when we changed the original dictionary, the copied dictionary (stored in variable categories_copy) remained the same. This means that we successfully copied the dictionary to a different memory location.

    But we shallow copied the dictionary. We know that, for a shallow copied composite object, the inner objects point at same memory location as that of the original composite object. You can see this in the following example:

    import copy
    
    categories = {
        'Fruits' : ['Apple', 'Banana', 'Mango'],
        'Flowers' : ['Rose', 'Sunflower', 'Tulip'],
    }
    
    categories_copy = copy.copy(categories)
    
    # checking if the inner object list 'Fruits' of both the dictionaries point to same memory address.
    print(f"""
    Do 'categories' and 'categories_copy' inner object share same memory address? 
    --> {id(categories_copy['Fruits']) == id(categories['Fruits'])}
    """)
    
    # checking if the outer objects (dictionaries) point to same memory address.
    print(f"""
    Do 'categories' and 'categories_copy' outer object share same memory address? 
    --> {id(categories_copy) == id(categories)}
    """)
    

    Output:

    Do ‘categories’ and ‘categories_copy’ inner object share same memory address?

    –> True

    Do ‘categories’ and ‘categories_copy’ outer object share same memory address?

    –> False

    In the above code, we used the same example as earlier. Then, we made use of the in-built function id() to extract and compare the memory addresses of both the dictionaries.

    For inner objects, the memory address is the same. But outer objects are located at different locations in the memory. Thus, we can say that while shallow copying objects, the inner objects are only referenced, while the outer objects are copied to a separate memory address.

    On the other hand, the deepcopy() function of the copy module copies the object completely (both inner and outer objects are stored at different memory locations). The following code shows how we can deep copy the objects within our code:

    import copy
    
    categories = {
        'Fruits' : ['Apple', 'Banana', 'Mango'],
        'Flowers' : ['Rose', 'Sunflower', 'Tulip'],
    }
    
    # deep copying the dictionary
    categories_copy = copy.deepcopy(categories)
    
    print(f"""
    Do 'categories' and 'categories_copy' inner object share same memory address? 
    --> {id(categories_copy['Fruits']) == id(categories['Fruits'])}
    """)
    
    print(f"""
    Do 'categories' and 'categories_copy' outer object share same memory address? 
    --> {id(categories_copy) == id(categories)}
    """)
    

    Output:

    Do ‘categories’ and ‘categories_copy’ inner object share same memory address?

    –> False

    Do ‘categories’ and ‘categories_copy’ outer object share same memory address?

    –> False

    In the code, we deep copied the dictionary by using the deepcopy() function. When we compared the memory addresses of the inner and the outer objects stored in both the identifiers, we can see that they are separately stored in the memory.

    So you’ll use a shallow copy or a deep copy depending upon the situation.

    For example, if you just want to copy the outer object and keep the nested object same for all, you should opt for a shallow copy. If you have defined a class to create students’ ID of grade X, then you might need to keep the self.grade = X for all the students. In such cases, you can just reference the nested object.

    Also, for non-nested objects, the shallow copy method fulfills the purpose, as there are no nested objects and shallow copying completely copies the outer object to a different memory location.

    On the other hand, if you want a complete, independent copy of the object, you should deep copy the object.

    More About Copying Objects in Python

    You can use the copy module for both immutable and mutable objects. But for immutable objects, you can also use assignment operator = for copying objects.

    Now, as I mentioned earlier, in this case too, the object is referenced when you use the = operator. But, when you mutate immutable objects, the mutated objects get stored at a different memory location. This makes the alias of the original object an independent object, pointing at the same memory address as earlier.

    Let’s understand this with an example:

    str1 = "String" # created a string object
    
    str2 = str1 # using '=' to reference the string stored in 'str1'
    
    print(str2, str1, sep='n') # printing the strings
    

    Output:

    String

    String

    Above, the variable str2 referenced the string stored in variable str1. Basically, str2 and str1 point at same memory address and str2 is just an alias of str1.

    But if we go further and modify the string in str1, then str1 starts to point at a new memory location (since a string is immutable, if it’s modified it gets stored at a different memory address). But str2 will still point at the previous memory address, commonly fulfilling the purpose of copying the objects.

    str1 = "String"
    
    str2 = str1
    
    # printing memory addresses of both the variables before mutation.
    print(f"""
    Memory address of str1: {id(str1)}
    Memory address of str2: {id(str2)}
    """)
    
    str1+='***' # concatenated the string '***' with str1.
    
    print(str2, str1, sep='n')
    
    # printing memory addresses of both the variables after mutation.
    print(f"""
    Memory address of str1: {id(str1)}
    Memory address of str2: {id(str2)}
    """)
    

    Output:

    Memory address of str1: 2652367074480

    Memory address of str2: 2652367074480

    String

    String***

    Memory address of str1: 2652367370736

    Memory address of str2: 2652367074480

    Note: Memory addresses may vary on your device from the ones shown above.

    Now, in the above example, we first created a string object and referenced it in another variable, and printed the memory addresses of both the variables. Then, we modified the original string, and again, printed the memory addresses of both the variables.

    In the output, we can see that the memory addresses of both the variables before mutation were the same. So you can see that both the variables were pointing at the same memory location. But after mutation, the variable str1 started pointing at a different memory location, thus making the alias str2 an independent object, which still points at the previous memory address.

    To sum up, you can use the = operator for storing a copy of the original object if you plan to modify it further in the program.

    Summary

    In this tutorial, you learned about copying objects in Python. Specifically, we talked about:

    • How the assignment operator = is used for referencing and not copying.

    • The built-in copy module, which provides functions that allow us to shallow copy and deep copy the objects in our program.

    • The concept of shallow copy and deep copy, which are essential when copying compound objects.

    • How a shallow copy copies the outer object and references the inner objects.

    • How a deep copy copies both the outer object and the inner objects.

    • How for immutable objects, the assignment operator works fine for copying the objects most of the time.

    Thanks for reading!

    Source: freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More 

    Hostinger
    Facebook Twitter Reddit Email Copy Link
    Previous ArticleData Loading with Python and AI
    Next Article Distribution Release: Ubuntu Cinnamon 25.04

    Related Posts

    Security

    Nmap 7.96 Launches with Lightning-Fast DNS and 612 Scripts

    May 14, 2025
    Common Vulnerabilities and Exposures (CVEs)

    CVE-2024-52290 – LF Edge eKuiper Cross-Site Scripting (XSS)

    May 14, 2025
    Leave A Reply Cancel Reply

    Hostinger

    Continue Reading

    How well does WSL work on the new Snapdragon X Elite laptops?

    Development

    Natural language boosts LLM performance in coding, planning, and robotics

    Artificial Intelligence

    Accelerate your Amazon Q implementation: starter kits for SMBs

    Machine Learning

    Dopo 16 anni, la release numero 3 di Pidgin, storico tool open-source multi-chat, è pronta ad uscire!

    Development

    Highlights

    Development

    Critical Flaws in WGS-804HPT Switches Enable RCE and Network Exploitation

    January 17, 2025

    Cybersecurity researchers have disclosed three security flaws in Planet Technology’s WGS-804HPT industrial switches that could…

    CVE-2025-4238 – PCMan FTP Server MGET Command Handler Buffer Overflow

    May 3, 2025

    As Part of JMeter WEB DRIVER(Selenium Scripts) Integration With Azure Pipeline and how can I add Headless Browser in Azure Pipeline

    July 7, 2024

    Indiana Jones and the Great Circle just got another patch improving ray tracing on Xbox and bringing these important bug fixes

    December 20, 2024
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.