What does a &= b
mean?
This depends on the implementation for the types of a
and b
, but semantics are essentially that
a &= b
is the update of a
with its “AND” for b
. That “AND” operation could be a set intersection, a binary AND operation, or some other operation that can be implemented by a programmer.
So there are multiple ways of implementing it.
In the following sections, I demonstrate __and__
and __iand__
and give multiple examples of types for which there are different semantics below (set
, in which the a
object is mutated in-place, and frozenset
and int
which are immutable, so the variable a
is now pointing to the new object).
Explanation
Understandable that you can’t find much reference on it. I find it hard to get references on this too, but they exist.
The i
in iand
means in-place, so it’s the in-place operator for &
. &=
calls the __iand__
operator, if it is implemented. If not implemented, it is the same as x = x & y
.
Built-in Example, Sets:
It’s primarily used to update the intersection of built-in set types:
>>> a = set('abc')
>>> a &= set('cbe')
>>> a
set(['c', 'b'])
which is the same as:
>>> a = set('abc')
>>> a.__iand__(set('cbe'))
set(['c', 'b'])
It is very similar to calling the set.intersection_update
method, and would be used in control flow as you would do an in-place update of any object or variable (if the object is immutable).
Unimplemented Built-in Example
The less commonly used immutable frozenset object would be replaced in memory on the inplace update, and the variable name would point to the new object in memory.
>>> a = frozenset('abc')
>>> a &= set('bce')
>>> a
frozenset({'c', 'b'})
In this case, since frozenset doesn’t implement an __iand__
method,
>>> a = frozenset('abc')
>>> a.__iand__(set('cbe'))
Traceback (most recent call last):
File "<pyshell#160>", line 1, in <module>
a = frozenset('abc'); a.__iand__(set('cbe'))
AttributeError: 'frozenset' object has no attribute '__iand__'
it *is (nearly) identical to
a = a & set('bce')
*(I say nearly because if you examine the bytecode, you’ll see that the underlying implementation treats sets and frozensets the same, even though frozensets don’t have __iand__
, and sets do, because each calls INPLACE_AND
, at least for compiled functions.)
Built-in Example, Binary Flags:
Similar to Sets, we can use the &=
to update the intersection of binary option flags where the value for True
is 1
. Below, we demonstrate that the “binary AND”, (akin to intersection) of the binary numbers 1110
and 1011
is 1010
:
>>> option_flags = int('1110', 2)
>>> option_flags
14
>>> option_flags &= int('1011', 2)
>>> option_flags
10
>>> bin(option_flags)
'0b1010'
Since int
objects are not mutable, like the frozenset
example, this actually only reassigns the variable option_flags
to the newly calculated value.