Google won't let me search |= so I'm having trouble finding relevant documentation. Anybody know?
Google won't let me search |= so I'm having trouble finding relevant documentation. Anybody know?
|= performs an in-place+ operation between pairs of objects. In particular, between:
In most cases, it is related to the | operator. See examples below.
Sets
For example, the union of two assigned sets s1 and s2 share the following equivalent expressions:
>>> s1 = s1 | s2 # 1
>>> s1 |= s2 # 2
>>> s1.__ior__(s2) # 3
where the final value of s1 is equivalent either by:
Example
Here we apply OR (|) and the in-place OR (|=) to sets:
>>> s1 = {"a", "b", "c"}
>>> s2 = {"d", "e", "f"}
>>> # OR, |
>>> s1 | s2
{'a', 'b', 'c', 'd', 'e', 'f'}
>>> s1 # `s1` is unchanged
{'a', 'b', 'c'}
>>> # In-place OR, |=
>>> s1 |= s2
>>> s1 # `s1` is reassigned
{'a', 'b', 'c', 'd', 'e', 'f'}
Dictionaries
In Python 3.9+, new merge (|) and update (|=) operators are proposed between dictionaries. Note: these are not the same as set operators mentioned above.
Given operations between two assigned dicts d1 and d2:
>>> d1 = d1 | d2 # 1
>>> d1 |= d2 # 2
where d1 is equivalent via:
d1.update(d2)Example
Here we apply merge (|) and update (|=) to dicts:
>>> d1 = {"a": 0, "b": 1, "c": 2}
>>> d2 = {"c": 20, "d": 30}
>>> # Merge, |
>>> d1 | d2
{"a": 0, "b": 1, "c": 20, "d": 30}
>>> d1
{"a": 0, "b": 1, "c": 2}
>>> # Update, |=
>>> d1 |= d2
>>> d1
{"a": 0, "b": 1, "c": 20, "d": 30}
Counters
The collections.Counter is related to a mathematical datastructure called a multiset (mset). It is basically a dict of (object, multiplicity) key-value pairs.
Given operations between two assigned counters c1 and c2:
>>> c1 = c1 | c2 # 1
>>> c1 |= c2 # 2
where c1 is equivalent via:
A union of multisets contains the maximum multiplicities per entry. Note, this does not behave the same way as between two sets or between two regular dicts.
Example
Here we apply union (|) and the in-place union (|=) to Counters:
import collections as ct
>>> c1 = ct.Counter({2: 2, 3: 3})
>>> c2 = ct.Counter({1: 1, 3: 5})
>>> # Union, |
>>> c1 | c2
Counter({2: 2, 3: 5, 1: 1})
>>> c1
Counter({2: 2, 3: 3})
>>> # In-place Union, |=
>>> c1 |= c2
>>> c1
Counter({2: 2, 3: 5, 1: 1})
Numbers
Lastly, you can do binary math.
Given operations between two assigned numbers n1 and n2:
>>> n1 = n1 | n2 # 1
>>> n1 |= n2 # 2
where n1 is equivalent via:
Example
Here we apply bitwise OR (|) and the in-place bitwise OR (|=) to numbers:
>>> n1 = 0
>>> n2 = 1
>>> # Bitwise OR, |
>>> n1 | n2
1
>>> n1
0
>>> # In-place Bitwise OR, |=
>>> n1 |= n2
>>> n1
1
Review
This section briefly reviews some bitwise math. In the simplest case, the bitwise OR operation compares two binary bits. It will always return 1 except when both bits are 0.
>>> assert 1 == (1 | 1) == (1 | 0) == (0 | 1)
>>> assert 0 == (0 | 0)
We now extend this idea beyond binary numbers. Given any two integral numbers (lacking fractional components), we apply the bitwise OR and get an integral result:
>>> a = 10
>>> b = 16
>>> a | b
26
How? In general, the bitwise operations follow some "rules":
Let's apply these rules to our regular integers above.
(1) Compare binary equivalents, seen here as strings (0b denotes binary):
>>> bin(a)
'0b1010'
>>> bin(b)
'0b10000'
(2) Apply a bitwise OR operation to each column (0 when both are 0, else 1):
01010
10000
-----
11010
(3) Return the result in the given type, e.g. base 10, decimal:
>>> int(0b11010)
26
The internal binary comparison means we can apply the latter to integers in any base, e.g. hex and octal:
>>> a = 10 # 10, dec
>>> b = 0b10000 # 16, bin
>>> c = 0xa # 10, hex
>>> d = 0o20 # 16, oct
>>> a | b
26
>>> c | d
26
See Also
__ior__() method to iterate iterables in a MutableSet abstract base class|= to update a set+The in-place bitwise OR operator cannot be applied to literals; assign objects to names.
++Special methods return the same operations as their corresponding operators.
It's bitwise or.
Let's say we have 32 | 10, picture 32 and 10 in binary:
32 = 10 0000
10 = 00 1010
Now because | is the OR operation, do a bitwise-or on the two numbers
i.e 1 or 0 --> 1, 0 or 0 --> 0. Continue this down the chain:
10 0000 | 00 1010 = 10 1010.
Now change the binary into a decimal, 10 1010 = 42.
For |=, think of the known examples, x +=5. It means x = x + 5, therefore if we have x |= 5, it means x = x bitwiseor with 5.
In Python,|=(ior) works like union operation. like if x=5 and x|=5 then both the value will first convert in binary value then the union operation will perform and we get the answer 5.
To give a use-case (after spending time with the other answers):
def process(item):
return bool(item) # imagine some sort of complex processing taking place above
def any_success(data): # return True if at least one is successful
at_least_one = False
for item in data:
at_least_one |= process(item)
return at_least_one
>>> any_success([False, False, False])
False
>>> any_success([True, False, False])
True
>>> any_success([False, True, False])
True
Basically any without the short-circuiting: might be useful if you need to process every item and record at least one success etc.
See also the caveats in this answer
It means bitwise OR operation.
Example :
x = 5
x |= 3 #which is similar to x = x | 3
print(x)
Answer : 7
How does it works?
The binary of 5 is : 0 1 0 1
The binary of 3 is : 0 0 1 1
OR operation : (If one of 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 1 1 1 #Binary of 7
So, the answer is 7
Hopefully this also helps others to understand:
dict1 = {'a': 'dict1', 'b': 'dict1', 'c': 'dict1'}
dict2 = {'c': 'dict2', 'd': 'dict2', 'e': 'dict2'}
dict3 = dict1.copy()
dict3 = dict3 | dict2
dict4 = dict1.copy()
dict4 |= dict2
print(f'dict1:\n {dict1}')
print(f'dict2:\n {dict2}')
print(f'dict1 after dict1 = dict1 | dict2 (dict2 index c replaces dict1 index c, items in dict1 are discarded if present in dict2):\n {dict3}')
print(f'dict1 after dict1 |= dict2 (same behaviour as dict1 = dict1 | dict2):\n {dict4}')
dict5 = dict1.copy()
dict5 = dict2 | dict5
dict6 = dict2.copy()
dict6 |= dict1
print(f'dict1 after dict1 = dict2 | dict1 (dict2 index c is missing, dict1 index c was retained, items in dict2 are discarded if present in dict1):\n {dict5}')
print(f'dict2 after dict2 |= dict1 (same behaviour as dict2 = dict2 | dict1):\n {dict6}')
dict1:
{'a': 'dict1', 'b': 'dict1', 'c': 'dict1'}
dict2:
{'c': 'dict2', 'd': 'dict2', 'e': 'dict2'}
dict1 after dict1 = dict1 | dict2 (dict2 index c replaces dict1 index c, items in dict1 are discarded if present in dict2):
{'a': 'dict1', 'b': 'dict1', 'c': 'dict2', 'd': 'dict2', 'e': 'dict2'}
dict1 after dict1 |= dict2 (same behaviour as dict1 = dict1 | dict2):
{'a': 'dict1', 'b': 'dict1', 'c': 'dict2', 'd': 'dict2', 'e': 'dict2'}
dict1 after dict1 = dict2 | dict1 (dict2 index c is missing, dict1 index c was retained, items in dict2 are discarded if present in dict1):
{'c': 'dict1', 'd': 'dict2', 'e': 'dict2', 'a': 'dict1', 'b': 'dict1'}
dict2 after dict2 |= dict1 (same behaviour as dict2 = dict2 | dict1):
{'c': 'dict1', 'd': 'dict2', 'e': 'dict2', 'a': 'dict1', 'b': 'dict1'}