How to clone or copy a set in Python?

PythonSetCloneShallow Copy

Python Problem Overview


For copying a list: shallow_copy_of_list = old_list[:].

For copying a dict: shallow_copy_of_dict = dict(old_dict).

But for a set, I was worried that a similar thing wouldn't work, because saying new_set = set(old_set) would give a set of a set?

But it does work. So I'm posting the question and answer here for reference. In case anyone else has the same confusion.

Python Solutions


Solution 1 - Python

Both of these will give a duplicate of a set:

shallow_copy_of_set = set(old_set)

Or:

shallow_copy_of_set = old_set.copy() #Which is more readable.

The reason that the first way above doesn't give a set of a set, is that the proper syntax for that would be set([old_set]). Which wouldn't work, because sets can't be elements in other sets, because they are unhashable by virtue of being mutable. However, this isn't true for frozensets, so e.g. frozenset(frozenset(frozenset([1,2,3]))) == frozenset([1, 2, 3]).

So a rule of thumb for replicating any of instance of the basic data structures in Python (lists, dict, set, frozenset, string):

a2 = list(a)      #a is a list
b2 = set(b)       #b is a set
c2 = dict(c)      #c is a dict
d2 = frozenset(d) #d is a frozenset
e2 = str(e)       #e is a string
#All of the above give a (shallow) copy.

So, if x is either of those types, then

shallow_copy_of_x = type(x)(x) #Highly unreadable! But economical.

Note that only dict, set and frozenset have the built-in copy() method. It would probably be a good idea that lists and strings had a copy() method too, for uniformity and readability. But they don't, at least in Python 2.7.3 which I'm testing with.

Solution 2 - Python

Besides the type(x)(x) hack, you can import copy module to make either shallow copy or deep copy:

In [29]: d={1: [2,3]}

In [30]: sd=copy.copy(d)
    ...: sd[1][0]=321
    ...: print d
{1: [321, 3]}

In [31]: dd=copy.deepcopy(d)
    ...: dd[1][0]=987
    ...: print dd, d
{1: [987, 3]} {1: [321, 3]}

From the docstring:

Definition: copy.copy(x)
Docstring:
Shallow copy operation on arbitrary Python objects.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEvgeni SergeevView Question on Stackoverflow
Solution 1 - PythonEvgeni SergeevView Answer on Stackoverflow
Solution 2 - PythonzhangxaochenView Answer on Stackoverflow