What does |= (ior) do in Python?

Python

Python Problem Overview


Google won't let me search |= so I'm having trouble finding relevant documentation. Anybody know?

Python Solutions


Solution 1 - Python

|= 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:

  1. an assigned OR operation
  2. an in-place OR operation
  3. an in-place OR operation via special method++

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:

  1. an assigned merge-right operation
  2. an in-place merge-right (update) operation; equivalent to 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:

  1. an assigned union operation
  2. an in-place union operation

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:

  1. an assigned bitwise OR operation
  2. an in-place bitwise OR operation

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":

  1. internally compare binary equivalents
  2. apply the operation
  3. return the result as the given type

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

+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.

Solution 2 - Python

In Python, and many other programming languages, | is the bitwise-OR operation. |= is to | as += is to +, i.e. a combination of operation and asignment.

So var |= value is short for var = var | value.

A common use case is to merge two sets:

>>> a = {1,2}; a |= {3,4}; print(a)
{1, 2, 3, 4}

Solution 3 - Python

When used with sets it performs union operation.

Solution 4 - Python

This is just an OR operation between the current variable and the other one. Being T=True and F=False, see the output graphically:

| r | s | r|=s | | - | - | - | | T | T | T | T | F | T | F | T | T | F | F | F

For example:

>>> r=True
>>> r|=False
>>> r
True
>>> r=False
>>> r|=False
>>> r
False
>>> r|=True
>>> r
True

Solution 5 - Python

It performs a binary bitwise OR of the left-hand and right-hand sides of the assignment, then stores the result in the left-hand variable.

http://docs.python.org/reference/expressions.html#binary-bitwise-operations

Solution 6 - Python

It's bitwise or. Let's say we have 32 |= 10, picture 32 and 10 is binary.

32 = 10 0000
10 = 00 1010

Now because | is or, 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.

Solution 7 - Python

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.

Solution 8 - Python

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

Solution 9 - Python

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'}

Solution 10 - Python

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSean W.View Question on Stackoverflow
Solution 1 - PythonpylangView Answer on Stackoverflow
Solution 2 - PythonDaniel StutzbachView Answer on Stackoverflow
Solution 3 - PythonKondalarao VView Answer on Stackoverflow
Solution 4 - PythonfedorquiView Answer on Stackoverflow
Solution 5 - PythonBrandon RhodesView Answer on Stackoverflow
Solution 6 - PythonmemeKingView Answer on Stackoverflow
Solution 7 - Pythonaanchal.sView Answer on Stackoverflow
Solution 8 - PythonscharfmnView Answer on Stackoverflow
Solution 9 - PythonNotoriousPyroView Answer on Stackoverflow
Solution 10 - PythonXpressGeekView Answer on Stackoverflow