¿Qué hace | = (ior) en Python?

112

Google no me permite realizar búsquedas, |=por lo que tengo problemas para encontrar documentación relevante. ¿Alguien sabe?

Sean W.
fuente
5
Creo que es relevante señalar, como en la respuesta de sunny a continuación, que |también se usa como operador de unión de conjunto
TallChuck
10
en 2019 Google te permitirá buscar` | = `! :-)
rbennell

Respuestas:

45

|=realiza una operación + in situ entre pares de objetos. En particular, entre:

En la mayoría de los casos, está relacionado con el |operador. Vea los ejemplos a continuación.

Conjuntos

Por ejemplo, la unión de dos conjuntos asignados s1y s2comparten las siguientes expresiones equivalentes:

>>> s1 = s1 | s12                                          # 1
>>> s1 |= s2                                               # 2
>>> s1.__ior__(s2)                                         # 3

donde el valor final de s1es equivalente por:

  1. una operación OR asignada
  2. una operación de quirófano en el lugar
  3. una operación OR in situ mediante un método especial ++

Ejemplo

Aquí aplicamos OR ( |) y el OR ( |=) en el lugar a los conjuntos :

>>> s1 = {"a", "b", "c"}
>>> s2 = {"d", "e", "f"}

>>> # OR, | 
>>> s1 | s2
{'a', 'b', 'c', 'd', 'e', 'f'}
>>> s1                                                     # `s1` is unchanged
{'a', 'b', 'c'}

>>> # Inplace OR, |=
>>> s1 |= s2
>>> s1                                                     # `s1` is reassigned
{'a', 'b', 'c', 'd', 'e', 'f'}

Diccionarios

En Python 3.9+ , se proponen nuevos operadores de combinación ( |) y actualización ( |=) entre diccionarios. Nota: estos no son los mismos que los operadores de conjuntos mencionados anteriormente.

Operaciones dadas entre dos dictados asignados d1y d2:

>>> d1 = d1 | d2                                           # 1
>>> d1 |= d2                                               # 2

donde d1es equivalente a través de:

  1. una operación de combinación derecha asignada
  2. una operación de fusión derecha (actualización) en el lugar; equivalente ad1.update(d2)

Ejemplo

Aquí aplicamos merge ( |) y update ( |=) a los dictados :

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

Contadores

El collections.Counterestá relacionado con una estructura de datos matemática llamada multiset (mset). Básicamente es un diccionario de pares clave-valor (objeto, multiplicidad).

Operaciones dadas entre dos contadores asignados c1y c2:

>>> c1 = c1 | c2                                           # 1
>>> c1 |= c2                                               # 2

donde c1es equivalente a través de:

  1. una operación sindical asignada
  2. una operación sindical en el lugar

Una unión de conjuntos múltiples contiene las multiplicidades máximas por entrada. Tenga en cuenta que esto no se comporta de la misma manera que entre dos conjuntos o entre dos dictados regulares.

Ejemplo

Aquí aplicamos union ( |) y la unión in situ ( |=) a los contadores :

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

>>> # Inplace Union, |=
>>> c1 |= c2
>>> c1
Counter({2: 2, 3: 5, 1: 1})

Números

Por último, puedes hacer matemáticas binarias.

Operaciones dadas entre dos números asignados n1y n2:

>>> n1 = n1 | n2                                           # 1
>>> n1 |= n2                                               # 2

donde n1es equivalente a través de:

  1. una operación OR bit a bit asignada
  2. una operación OR bit a bit en el lugar

Ejemplo

Aquí aplicamos OR ( |) bit a bit y OR ( |=) bit a bit in situ a los números :

>>> n1 = 0
>>> n2 = 1

>>> # Bitwise OR, |
>>> n1 | n2
1
>>> n1
0

>>> # Inplace Bitwise OR, |=
>>> n1 |= n2
>>> n1
1

revisión

Esta sección revisa brevemente algunas matemáticas bit a bit. En el caso más simple, la operación OR bit a bit compara dos bits binarios. Siempre regresará 1excepto cuando ambos bits sean 0.

>>> assert 1 == (1 | 1) == (1 | 0) == (0 | 1)
>>> assert 0 == (0 | 0)

Extendemos ahora esta idea más allá de los números binarios. Dados dos números enteros cualesquiera (que carecen de componentes fraccionarios), aplicamos el OR bit a bit y obtenemos un resultado integral:

>>> a = 10 
>>> b = 16 
>>> a | b
26

¿Cómo? En general, las operaciones bit a bit siguen algunas "reglas":

  1. comparar internamente equivalentes binarios
  2. aplicar la operación
  3. devuelve el resultado como el tipo dado

Apliquemos estas reglas a nuestros enteros regulares anteriores.

(1) Compare equivalentes binarios, vistos aquí como cadenas ( 0bdenota binario):

>>> bin(a)
'0b1010'
>>> bin(b)
'0b10000'

(2) Aplicar una operación OR bit a bit a cada columna ( 0cuando ambos son 0, de lo contrario 1):

01010
10000
-----
11010

(3) Devuelve el resultado en el tipo dado, por ejemplo, base 10, decimal:

>>> int(0b11010)
26

La comparación binaria interna significa que podemos aplicar este último a números enteros en cualquier base, por ejemplo, hexadecimal y octal:

>>> c = 0xa
>>> d = 0o32
>>> c | d
26

Ver también

+ El operador OR bit a bit en el lugar no se puede aplicar a literales; asignar objetos a los nombres.

++ Los métodos especiales devuelven las mismas operaciones que sus operadores correspondientes.

pylang
fuente
2
Para ser perfectamente claro, agregaría a la demostración que después de hacer la asignación regular (x = x | y) el id (x) ha cambiado porque es un nuevo objeto, mientras que | = mantiene el mismo id porque es el x original que se modifica, de ahí el nombre "inplace".
Florimond
1
Esta debería ser la respuesta principal, es la más exhaustiva.
Nick
En la sección de números, afirma que la segunda declaración realiza operaciones en el lugar. Creo que no es cierto, ya que los ints no son mutables en Python.
Asocia
106

En Python, y muchos otros lenguajes de programación, |es la operación OR bit a bit . |=es |como +=es +, es decir, una combinación de operación y asignación.

Entonces var |= valuees la abreviatura de var = var | value.

Un caso de uso común es fusionar dos conjuntos:

>>> a = {1,2}; a |= {3,4}; print(a)
{1, 2, 3, 4}
Daniel Stutzbach
fuente
21
¿Puede darnos un ejemplo?
minerales
He dado un caso de uso que encontré a continuación
scharfmn
53

Cuando se usa con conjuntos, realiza una operación de unión.

soleado
fuente
1
Estaba leyendo un código y |=se usó en un contexto establecido, y no fue hasta que me di cuenta y lo descubrí que noté que esta respuesta también estaba aquí
TallChuck
41

Esta es solo una operación OR entre la variable actual y la otra. Siendo T=Truey F=False, vea la salida gráficamente:

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

Por ejemplo:

>>> r=True
>>> r|=False
>>> r
True
>>> r=False
>>> r|=False
>>> r
False
>>> r|=True
>>> r
True
fedorqui 'Así que deja de hacer daño'
fuente
7
Esto da una impresión algo deformada del operador; |es un operador or bit a bit para enteros, no específicamente un operador booleano, y para cualquier otra cosa que no sea bools, en realidad no producirá Trueo generará Falseresultados. booles una subclase de int, y para ser agradable, la sobrecargaron para boolseguir produciendo True/ Falsesalidas, pero en la mayoría de los casos, las operaciones booleanas deben hacerse con or, no |. Los usos normales de |son bit a bit-or, o set-union. Mejores ejemplos de uso sería algo como lo a = 0b1001; a |= 0b0010; print(bin(a))que produce 0b1011.
ShadowRanger
3

Es bit a bit o. Digamos que tenemos 32 |= 10, la imagen 32 y 10 es binaria.

32 = 10 0000
10 = 00 1010

Ahora porque | es o, haz un bit a bit o en los dos números

es decir, 1 o 0 -> 1, 0 o 0 -> 0. Continúe con esto en la cadena

10 0000 | 00 1010 = 10 1010.

Ahora cambia el binario a decimal, 10 1010 = 42.

Para | =, pensar en los ejemplos conocidos, x +=5. Significa, x = x + 5,por tanto, si tenemos x |= 5, significa x = x bitwiseor with 5.

memes
fuente
esta es la explicación que estaba buscando, todo el mundo hablaba de sets y bools pero nadie mencionó su uso con números.
Ankush Verma
El ejemplo que dio no es 32 |= 10sino más bien 32 | 10. Solo para aclarar esto para futuros lectores :)
sniper71
@ sniper71 cuál es el resultado de 32 | = 10
Future-Jim
2

Para dar un caso de uso (después de pasar tiempo con las otras respuestas):

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

Básicamente anysin el cortocircuito: podría ser útil si necesita procesar cada elemento y registrar al menos un éxito, etc.

Vea también las advertencias en esta respuesta

scharfmn
fuente
1

En Python, | = (ior) funciona como una operación de unión. como si x = 5 y x | = 5, entonces ambos valores se convertirán primero en valor binario, luego se realizará la operación de unión y obtendremos la respuesta 5.

aanchal.s
fuente