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 set
s can't be elements in other set
s, because they are unhashable by virtue of being mutable. However, this isn't true for frozenset
s, 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.