51

Are sets in Python mutable?


In other words, if I do this:

x = set([1, 2, 3])
y = x
y |= set([4, 5, 6])

Are x and y still pointing to the same object, or was a new set created and assigned to y?

asked Jan 7, 2013 at 9:51
10
  • 5
    It is easier to detect than to ask about... print x is y would be applicable as well here. Commented Jan 7, 2013 at 9:54
  • 2
    Erm... Are all these down votes because the question is about something that is easy to check? Because I don't currently have access to a Python interpreter, and I couldn't find the answer online, so that's a stupid reason to down vote a question. Commented Jan 7, 2013 at 10:07
  • 6
    If you have access to the internet, how do you not have access to an interpreter? There are numerous in-browser interpreters, as a quick Google search will show you. Commented Jan 7, 2013 at 10:19
  • 2
    Also, you should be able to immediately see that sets are mutable by looking at the docs. Commented Jan 7, 2013 at 10:25
  • 2
    My +1 to the question. The wording may not be the same what is the author thinking about. (Would the question "Are sets in Python really mutable?" be more acceptable?). And also, almost everything can be found in the doc. This way, any question that can be explained via studying the doc would not be legitimate. I do not think there are "stupid questions". Everyone is at a different level. Some beginners may be 70 years old, some experts can be 12. There are different ways of getting knowledge. Commented Jan 7, 2013 at 11:35

9 Answers 9

68
>>>> 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.

answered Jan 7, 2013 at 9:53
Sign up to request clarification or add additional context in comments.

4 Comments

Note there exists a built-in immutable set class: frozenset.
@celestialroad @Tom, it's update, see docs.python.org/2/library/stdtypes.html#set
See my answer, sets can contain mutable types.
Strictly speaking, set elements have to be hashable, not necessarily immutable. Mutable types can be reliably hashable as long as the hash only depends on immutable parts of the object.
23

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} change x?

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).

answered Jan 7, 2013 at 10:00

15 Comments

I don't see how the two questions are different. If sets were not mutable, y would be pointing to a different object than x, just like with string concatenation.
@Codemonkey False: x = "hello"; y = x; y is x is True. The syntax y = x always makes y and x point to the same object. Can you explain what you mean by "like with string concatenation"?
@katrielalex But if you then do concatenation, "y += " world", y points to a different object than x, whereas with a mutable object it doesn't, which is what he's doing in the question.
@agf right, that's a side-effect of mutable objects in the stdlib having __i<foo>__ methods. There's no guarantee that a mutable object will have these, nor that an immutable won't. It's an implementation detail.
You can't assign to s[2] because sets aren't ordered. You can do s.add(4) to add 4 to the set, though.
|
14

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 item 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.

robertspierre
5,7313 gold badges43 silver badges65 bronze badges
answered Jul 27, 2018 at 15:01

Comments

3

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
answered Feb 7, 2018 at 8:32

4 Comments

which textbook was this ?
Learning python by Mark Lutz (5th Edition). Maybe the textbook was referring to some python version which was released at that point of time.
If you really want immutable sets, there is something called "frozenset" in python where sets have immutability.
Is the textbook reference referrring to pawandeep singh's answer? That contains a screenshot from a textbook.
2
print x,y

and you see they both point to the same set:

set([1, 2, 3, 4, 5, 6]) set([1, 2, 3, 4, 5, 6])
answered Jan 7, 2013 at 9:53

Comments

2

Sets are mutable, you can add to them. The items they contain CAN BE MUTABLE THEY MUST BE HASHABLE. I didn't see any correct answers in this post so here is the code

class MyClass:
"""
 This class is hashable, however, the hashes are
 unique per instance not the data so a set will
 have no way to determine equality
"""
def __init__(self):
 self.my_attr = "no-unique-hash"
def __repr__(self):
 return self.my_attr
class MyHashableClass:
 """
 This object implements __hash__ and __eq__ and will
 produce the same hash if the data is the same. 
 That way a set can remove equal objects.
 """
 def __init__(self):
 self.my_attr = "unique-hash"
 def __hash__(self):
 return hash(str(self))
 def __eq__(self, other):
 return hash(self) == hash(other)
 def __repr__(self):
 return self.my_attr
myclass_instance1 = MyClass()
myclass_instance2 = MyClass()
my_hashable_instance1 = MyHashableClass()
my_hashable_instance2 = MyHashableClass()
my_set = {
 myclass_instance1,
 myclass_instance2,
 my_hashable_instance1,
 my_hashable_instance2, # will be removed, not unique
} # sets can contain mutuable types
# The only objects set can not contain are objects
# with the __hash__=None, such as List, Dict, and Sets
print(my_set)
# prints {unique-hash, no-unique-hash, no-unique-hash }
my_hashable_instance1.my_attr = "new-hash" # mutating the object
# now that the hashes between the objects are differrent
# instance2 can be added
my_set.add(my_hashable_instance2) 
print(my_set)
# {new-hash, no-unique-hash, no-unique-hash, unique-hash}
answered Feb 3, 2023 at 17:10

2 Comments

Just to clarify a type being hashable does not mean it is immutable
You should point out that to be reliable, the hash should only depend on immutable parts of the object. Just because an object has a hash doesn't mean it's going to work well.
2

Sets are mutable

s = {2,3,4,5,6}
type(s)
<class 'set'>
s.add(9)
s
{2, 3, 4, 5, 6, 9}

We are able to change elements of set

chepner
539k77 gold badges596 silver badges748 bronze badges
answered Jul 11, 2019 at 10:55

Comments

1

Yes, Python sets are mutable because we can add, delete elements into set, but sets can't contain mutable items into itself. Like the below code will give an error:

s = set([[1,2,3],[4,5,6]])

So sets are mutable but can't contain mutable items, because set internally uses hashtable to store its elements so for that set elements need to be hashable. But mutable elements like list are not hashable.

Note:
Mutable elements are not hashable
Immutable elements are hashable

Just like key of a dictionary can't be a list.

ejderuby
7356 silver badges23 bronze badges
answered Aug 14, 2019 at 12:30

1 Comment

Mutable types can be hashable. You just need to ensure that mutating an object does not change its hash.
-4

I don't think Python sets are mutable as mentioned clearly in book "Learning Python 5th Edition by Mark Lutz - O'Reilly Publications"

Enter image description here

Peter Mortensen
31.3k22 gold badges110 silver badges134 bronze badges
answered Dec 25, 2017 at 7:13

1 Comment

The elements of the set are immutable, the set itself is mutable.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.