Are Python sets mutable?
>>>> x = set([1, 2, 3])
>>>> y = x
>>>>
>>>> y |= set([4, 5, 6])
>>>> print x
set([1, 2, 3, 4, 5, 6])
>>>> print y
set([1, 2, 3, 4, 5, 6])
- Sets are unordered.
- Set elements are unique. Duplicate elements are not allowed.
- A set itself may be modified, but the elements contained in the set must be of an immutable type.
set1 = {1,2,3}
set2 = {1,2,[1,2]} --> unhashable type: 'list'
# Set elements should be immutable.
Conclusion: sets are mutable.
After changing the set, even their object references match. I don't know why that textbook says sets are immutable.
>>> s1 ={1,2,3}
>>> id(s1)
140061513171016
>>> s1|={5,6,7}
>>> s1
{1, 2, 3, 5, 6, 7}
>>> id(s1)
140061513171016
Python sets are classified into two types. Mutable and immutable. A set created with 'set' is mutable while the one created with 'frozenset' is immutable.
>>> s = set(list('hello'))
>>> type(s)
<class 'set'>
The following methods are for mutable sets.
s.add(item) -- Adds item to s. Has no effect if list
is already in s.
s.clear() -- Removes all items from s.
s.difference_update(t) -- Removes all the items from s that are also in t.
s.discard(item) -- Removes item from s. If item is not a member of s, nothing happens.
All these operations modify the set s in place. The parameter t can be any object that supports iteration.
Your two questions are different.
Are Python sets mutable?
Yes: "mutable" means that you can change the object. For example, integers are not mutable: you cannot change the number 1
to mean anything else. You can, however, add elements to a set, which mutates it.
Does
y = x; y |= {1,2,3}
changex
?
Yes. The code y = x
means "bind the name y
to mean the same object that the name x
currently represents". The code y |= {1,2,3}
calls the magic method y.__ior__({1,2,3})
under the hood, which mutates the object represented by the name y
. Since this is the same object as is represented by x
, you should expect the set to change.
You can check whether two names point to precisely the same object using the is
operator: x is y
just if the objects represented by the names x
and y
are the same object.
If you want to copy an object, the usual syntax is y = x.copy()
or y = set(x)
. This is only a shallow copy, however: although it copies the set object, the members of said object are not copied. If you want a deepcopy, use copy.deepcopy(x)
.