M. Bailey
M. Bailey

Reputation: 59

Why does Python "&=" set operator act differently than "&=" integer operation?

Why does this set operation change set s? It does not work the same way for the integer (bitwise) version of the same operator....

Set Operation &= (changes s):

s = set('abc')
t = set('bcd')
u=s
print u, s, t
u &= t
print u, s, t

results:

set(['a', 'c', 'b']) set(['a', 'c', 'b']) set(['c', 'b', 'd'])

set(['c', 'b']) set(['c', 'b']) set(['c', 'b', 'd'])

Bitwise operation &= (does not change s):

s = 7
t = 3
u=s
print u, s, t
u &= t
print u, s, t

Result:

7 7 3

3 7 3

Upvotes: 5

Views: 80

Answers (1)

Alex Hall
Alex Hall

Reputation: 36043

Integers implement the & operation but not the &= operation, so when you use x &= y it is expanded to x = x & y which simply reassigns the x variable rather than modifying its internal state (it wouldn't make much sense for & to mutate a value, just like it wouldn't make sense for +). Same for frozensets.

Sets implement the &= operation so it's not expanded to a variable reassignment but rather mutates the left hand side of the operator.

Tuples implement neither & nor &= so an error makes sense. However you get the same effect with +=: for tuples += is expanded, for lists it's an in-place mutation because lists are mutable.

Any class can implement their own version of these operators. See here for details. In particular & corresponds to __and__ and &= to __iand__.

If you think about it, it's a sensible convention for mutable classes to implement the in-place operators to allow direct modification, but not immutable classes.

Upvotes: 5

Related Questions