
When you need a separate version of a set that you can modify without affecting the original, you need to copy sets in Python. Simply assigning a set to a new variable does not create a copy — it creates a reference to the same set. Python copy sets operations give you proper independent copies using the copy method, the set constructor, and other techniques so your original data stays safe.
Before learning how to copy sets, it helps to understand what happens when you assign a set to a new variable. In Python, the assignment operator does not create a new set. Instead, both variables point to the same set object in memory.
original = {"apple", "banana", "cherry"}
reference = original
reference.add("date")
print("Original:", original)
print("Reference:", reference)
Output
Original: {'apple', 'banana', 'cherry', 'date'}
Reference: {'apple', 'banana', 'cherry', 'date'}
Adding an element to reference also changed original because both variables refer to the exact same set. This is why you need to properly copy sets in Python when you want two independent collections.
You can verify that both variables point to the same object using the id function.
original = {1, 2, 3}
reference = original
print("Same object:", id(original) == id(reference))
Output
Same object: True
The copy() method is the most straightforward way to copy a set in Python. It creates a shallow copy of the set, returning a new set with the same elements. Changes to the copy do not affect the original.
colors = {"red", "green", "blue"}
colors_copy = colors.copy()
colors_copy.add("yellow")
print("Original:", colors)
print("Copy:", colors_copy)
Output
Original: {'red', 'green', 'blue'}
Copy: {'red', 'green', 'blue', 'yellow'}
The copy method created an independent set. Adding yellow to colors_copy had no effect on the original colors set. This is the recommended way to copy sets in Python because it is clear, readable, and explicit about its purpose.
You can also verify that the copy is a different object in memory.
numbers = {10, 20, 30}
numbers_copy = numbers.copy()
print("Same object:", id(numbers) == id(numbers_copy))
print("Same elements:", numbers == numbers_copy)
Output
Same object: False
Same elements: True
The two sets contain the same elements but are stored as separate objects. Modifying one will never affect the other.
The set() constructor provides another way to copy sets in Python. When you pass an existing set to the set constructor, it creates a brand new set with all the same elements.
fruits = {"mango", "grape", "kiwi"}
fruits_copy = set(fruits)
fruits_copy.discard("grape")
print("Original:", fruits)
print("Copy:", fruits_copy)
Output
Original: {'mango', 'grape', 'kiwi'}
Copy: {'mango', 'kiwi'}
Removing grape from fruits_copy did not change the original fruits set. The set constructor works the same as the copy method for creating independent duplicates. This approach is useful when you want to convert other iterables into a set at the same time.
original = {"python", "java", "rust"}
duplicate = set(original)
duplicate.update({"go", "swift"})
print("Original:", original)
print("Duplicate:", duplicate)
Output
Original: {'python', 'java', 'rust'}
Duplicate: {'python', 'java', 'rust', 'go', 'swift'}
Python set unpacking with the curly brace syntax gives you a concise way to copy sets. You unpack all elements from the original set into a new set literal.
animals = {"cat", "dog", "rabbit"}
animals_copy = {*animals}
animals_copy.add("hamster")
print("Original:", animals)
print("Copy:", animals_copy)
Output
Original: {'cat', 'dog', 'rabbit'}
Copy: {'cat', 'dog', 'rabbit', 'hamster'}
The unpacking operator spread every element from animals into a new set. This creates a completely independent copy just like the other methods. This syntax is compact and works well when you want to combine copying with adding new elements in one step.
base = {1, 2, 3}
extended = {*base, 4, 5, 6}
print("Base:", base)
print("Extended:", extended)
Output
Base: {1, 2, 3}
Extended: {1, 2, 3, 4, 5, 6}
The copy module from the Python standard library provides a copy function that works on sets. For simple sets containing immutable elements like strings and numbers, copy.copy produces the same result as the set copy method.
import copy
scores = {95, 87, 72, 68, 91}
scores_copy = copy.copy(scores)
scores_copy.add(100)
print("Original:", scores)
print("Copy:", scores_copy)
Output
Original: {95, 87, 72, 68, 91}
Copy: {95, 87, 72, 68, 91, 100}
The copy module is more commonly used with nested data structures like lists of lists. Since sets can only contain hashable, immutable elements, a shallow copy is always sufficient for sets. You do not need copy.deepcopy for sets because sets cannot contain mutable objects like lists or dictionaries.
Copying an empty set works the same way as copying a set with elements. All methods produce a new empty set object.
empty = set()
empty_copy = empty.copy()
empty_copy.add("first")
print("Original:", empty)
print("Copy:", empty_copy)
print("Same object:", id(empty) == id(empty_copy))
Output
Original: set()
Copy: {'first'}
Same object: False
Even with no elements, the copy method creates a distinct set object. This confirms that copy always produces an independent set regardless of size.
Each method to copy sets in Python achieves the same result. Here is a side-by-side comparison showing that all approaches create independent copies with identical elements.
original = {"alpha", "beta", "gamma", "delta"}
copy_method = original.copy()
constructor_copy = set(original)
unpack_copy = {*original}
copy_method.add("epsilon")
constructor_copy.discard("beta")
unpack_copy.clear()
print("Original:", original)
print("copy() result:", copy_method)
print("set() result:", constructor_copy)
print("Unpack result:", unpack_copy)
Output
Original: {'alpha', 'beta', 'gamma', 'delta'}
copy() result: {'alpha', 'beta', 'gamma', 'delta', 'epsilon'}
set() result: {'alpha', 'gamma', 'delta'}
Unpack result: set()
Each copy was modified independently without any effect on the original set. The copy method is the most readable, the set constructor is versatile for type conversion, and unpacking is the most concise.
This example demonstrates every way to copy sets in Python, showing the difference between assignment and proper copying, and proving each method produces an independent set.
import copy
inventory = {"laptop", "phone", "tablet", "watch", "headset"}
assigned = inventory
copy_method = inventory.copy()
constructor_copy = set(inventory)
unpack_copy = {*inventory}
module_copy = copy.copy(inventory)
print("All equal to original:")
print(" assigned:", assigned == inventory)
print(" copy():", copy_method == inventory)
print(" set():", constructor_copy == inventory)
print(" unpack:", unpack_copy == inventory)
print(" copy.copy():", module_copy == inventory)
print("\nSame object as original:")
print(" assigned:", assigned is inventory)
print(" copy():", copy_method is inventory)
print(" set():", constructor_copy is inventory)
print(" unpack:", unpack_copy is inventory)
print(" copy.copy():", module_copy is inventory)
assigned.add("speaker")
print("\nAfter adding 'speaker' via assigned:")
print(" Original:", inventory)
print(" assigned:", assigned)
print(" copy():", copy_method)
print(" set():", constructor_copy)
print(" unpack:", unpack_copy)
print(" copy.copy():", module_copy)
copy_method.discard("laptop")
constructor_copy.clear()
unpack_copy.add("camera")
module_copy.discard("phone")
print("\nAfter modifying each copy independently:")
print(" Original:", inventory)
print(" copy():", copy_method)
print(" set():", constructor_copy)
print(" unpack:", unpack_copy)
print(" copy.copy():", module_copy)
Output
All equal to original:
assigned: True
copy(): True
set(): True
unpack: True
copy.copy(): True
Same object as original:
assigned: True
copy(): False
set(): False
unpack: False
copy.copy(): False
After adding 'speaker' via assigned:
Original: {'laptop', 'phone', 'tablet', 'watch', 'headset', 'speaker'}
assigned: {'laptop', 'phone', 'tablet', 'watch', 'headset', 'speaker'}
copy(): {'laptop', 'phone', 'tablet', 'watch', 'headset'}
set(): {'laptop', 'phone', 'tablet', 'watch', 'headset'}
unpack: {'laptop', 'phone', 'tablet', 'watch', 'headset'}
copy.copy(): {'laptop', 'phone', 'tablet', 'watch', 'headset'}
After modifying each copy independently:
Original: {'laptop', 'phone', 'tablet', 'watch', 'headset', 'speaker'}
copy(): {'phone', 'tablet', 'watch', 'headset'}
set(): set()
unpack: {'laptop', 'phone', 'tablet', 'watch', 'headset', 'camera'}
copy.copy(): {'laptop', 'tablet', 'watch', 'headset'}