What does the &=
operator mean in Python, and can you give me a working example?
I am trying to understand the __iand__
operator.
I just don't know what &=
means and have looked online but couldn't find it.
What does the &=
operator mean in Python, and can you give me a working example?
I am trying to understand the __iand__
operator.
I just don't know what &=
means and have looked online but couldn't find it.
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).
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
.
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).
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.)
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.
Contrary to some of the other answers, a &= b
is not shorthand for a = a & b
, though I admit it often behaves similarly for built-in immutable types like integers.
a &= b
can call the special method __iand__
if available. To see the difference, let's define a custom class:
class NewIand(object):
def __init__(self, x):
self.x = x
def __and__(self, other):
return self.x & other.x
def __iand__(self, other):
return 99
After which we have
>>> a = NewIand(1+2+4)
>>> b = NewIand(4+8+16)
>>> a & b
4
>>> a = a & b
>>> a
4
but
>>> a = NewIand(1+2+4)
>>> b = NewIand(4+8+16)
>>> a &= b
>>> a
99
It is a shorthand for:
a = a & b
&
is bitwise and
(see link for further explanation) if a
and b
are either int
or long
.
Otherwise, the statement is equivalent to:
a = a.__iand__(b)
if __iand__
is defined for a
.
to put it in simple terms. Under the hood it does bit-wise binary operation.
for example 5 in binary is 0101 and 3 in binary is 0011
now do "And" operation between them (when both are 1 the result is one, 0 otherwise) and you will get binary 0001 which means 1 in decimal.
x = 5
x &= 3
print(x)
output >>> 1
It means bitwise AND operation.
Example :
x = 5
x &= 3 #which is similar to x = x & 3
print(x)
Answer : 1
How does it works?
The binary of 5 is : 0 1 0 1
The binary of 3 is : 0 0 1 1
AND operation : (If both sides are 1/True then result is 1/True)
0 1 0 1 #Binary of 5
0 0 1 1 #Binary of 3
---------------------
0 0 0 1 #Binary of 1
So, the answer is 1