How to clone or copy a set in Python? How to clone or copy a set in Python? python python

How to clone or copy a set in 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 listb2 = set(b)       #b is a setc2 = dict(c)      #c is a dictd2 = frozenset(d) #d is a frozensete2 = 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.


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.