I have just tried the following in Python 2.6:
>>> foo = (set(),)
>>> foo[0] |= set(range(5))
TypeError: 'tuple' object does not support item assignment
>>> foo
(set([0, 1, 2, 3, 4]),)
>>> foo[0].update(set(range(10)))
>>> foo
(set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),)
I have several questions here:
- Why does
foo[0] |= set(range(5))update the set and throw an exception? - why does
foo[0].update(set(range(10)))work without a problem? Should it not have the same result as the first statement?
Edit Many people have pointed out, that tuples are immutable. I am aware of that. They have also pointed out, that |= would create a new set object and assign it to the tuple. That is wrong. See this:
>>> foo = set()
>>> bar = foo
>>> foo is bar
True
>>> foo |= set(range(5))
>>> foo
set([0, 1, 2, 3, 4])
>>> bar
set([0, 1, 2, 3, 4])
>>> foo is bar
True
This means that no new object has been created, but the existing one was modified. This should work with the tuple. Please note also that, although my first code throws a TypeError, the set within the tuple is still updated. That is the effect I am interested in. Why the TypeError, when the operation obviously was successful?
This shows that the statement
x[0] |= yis implemented by callingx[0].__ior__(y)and then assigning the returned value tox[0].setimplements in-place|=by havingset.__ior__returnself. However, the assignment tox[0]still takes place. The fact that it’s assigning the same value that was already there is irrelevant; it fails for the same reason that:fails.