O que | = (ior) faz em Python?

112

O Google não me deixa pesquisar, |=então estou tendo problemas para encontrar documentação relevante. Alguém sabe?

Sean W.
fonte
5
Acho que é relevante apontar, como na resposta de sunny abaixo, que |também é usado como o operador de união de conjuntos
TallChuck
10
em 2019 o Google permitirá que você pesquise` | = `! :-)
rbennell

Respostas:

45

|=executa uma operação + no local entre pares de objetos. Em particular, entre:

Na maioria dos casos, está relacionado ao |operador. Veja os exemplos abaixo.

Jogos

Por exemplo, a união de dois conjuntos atribuídos s1e s2compartilham as seguintes expressões equivalentes:

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

onde o valor final de s1é equivalente por:

  1. uma operação OR atribuída
  2. uma operação OR in-loco
  3. uma operação OR no local por meio de método especial ++

Exemplo

Aqui, aplicamos OR ( |) e OR ( |=) local aos 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'}

Dicionários

No Python 3.9+ , novos operadores merge ( |) e update ( |=) são propostos entre os dicionários. Nota: estes não são iguais aos operadores de conjunto mencionados acima.

Operações dadas entre dois dictos atribuídos d1e d2:

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

onde d1é equivalente via:

  1. uma operação de mesclagem atribuída
  2. uma operação de mesclagem (atualização) no local; equivalente ad1.update(d2)

Exemplo

Aqui aplicamos merge ( |) e update ( |=) aos 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}

Contadores

O collections.Counterestá relacionado a uma estrutura de dados matemática chamada multiset (mset). É basicamente um dicionário de pares de valores-chave (objeto, multiplicidade).

Operações dadas entre dois contadores atribuídos c1e c2:

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

onde c1é equivalente via:

  1. uma operação sindical atribuída
  2. uma operação sindical local

Uma união de multisets contém as multiplicidades máximas por entrada. Observe que isso não se comporta da mesma maneira que entre dois conjuntos ou entre dois dictos regulares.

Exemplo

Aqui, aplicamos union ( |) e union ( ) in-loco |=aos 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, você pode fazer matemática binária.

Operações dadas entre dois números atribuídos n1e n2:

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

onde n1é equivalente via:

  1. uma operação OR bit a bit atribuída
  2. uma operação OR bit a bit no local

Exemplo

Aqui, aplicamos OR bit a bit ( |) e o OR bit a bit no local ( |=) aos números :

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

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

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

Reveja

Esta seção revisa brevemente algumas matemáticas bit a bit. No caso mais simples, a operação bit a bit OR compara dois bits binários. Ele sempre retornará, 1exceto quando ambos os bits forem 0.

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

Agora estendemos essa ideia além dos números binários. Dados quaisquer dois números inteiros (sem componentes fracionários), aplicamos o OR bit a bit e obtemos um resultado integral:

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

Quão? Em geral, as operações bit a bit seguem algumas "regras":

  1. comparar internamente equivalentes binários
  2. aplicar a operação
  3. retorna o resultado como o tipo fornecido

Vamos aplicar essas regras aos nossos números inteiros regulares acima.

(1) Compare os equivalentes binários, vistos aqui como strings ( 0bdenota binário):

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

(2) Aplique uma operação OR bit a bit a cada coluna ( 0quando ambas estiverem 0, senão 1):

01010
10000
-----
11010

(3) Retorne o resultado no tipo fornecido, por exemplo, base 10, decimal:

>>> int(0b11010)
26

A comparação binária interna significa que podemos aplicar o último a inteiros em qualquer base, por exemplo, hex e octal:

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

Veja também

+ O operador OR bit a bit no local não pode ser aplicado a literais; atribuir objetos a nomes.

++ Os métodos especiais retornam as mesmas operações que seus operadores correspondentes.

pilang
fonte
2
Para ficar perfeitamente claro, eu acrescentaria à demonstração de que depois de fazer a atribuição regular (x = x | y) o id (x) mudou porque é um novo objeto, enquanto | = mantém o mesmo id porque é o x original que é modificado, daí o nome "local".
Florimond
1
Esta deve ser a resposta principal - é a mais exaustiva.
Nick
Na seção de números, você afirma que a segunda instrução opera no local. Acho que não é verdade, já que ints não são mutáveis ​​em Python.
Asocia
106

Em Python, e em muitas outras linguagens de programação, |é a operação bit a bit OR . |=é |como +=é +, ou seja, uma combinação de operação e atribuição.

Portanto, var |= valueé abreviação de var = var | value.

Um caso de uso comum é combinar dois conjuntos:

>>> a = {1,2}; a |= {3,4}; print(a)
{1, 2, 3, 4}
Daniel Stutzbach
fonte
21
Você pode dar um exemplo?
minerais
Apresentei
53

Quando usado com conjuntos, ele executa a operação de união.

ensolarado
fonte
1
Eu estava lendo um código e ele |=era usado no contexto definido, e não foi até que eu baguncei e descobri que percebi que essa resposta também estava aqui
TallChuck
41

Esta é apenas uma operação OR entre a variável atual e a outra. Sendo T=Truee F=False, veja a saída graficamente:

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

Por exemplo:

>>> r=True
>>> r|=False
>>> r
True
>>> r=False
>>> r|=False
>>> r
False
>>> r|=True
>>> r
True
fedorqui 'então pare de prejudicar'
fonte
7
Isso dá uma impressão meio distorcida do operador; |é um operador bit a bit para inteiros, não especificamente um operador booleano, e para qualquer coisa diferente de bools, ele não irá realmente produzir Trueou dar Falsesaída. boolé uma subclasse de int, e para ser bom, eles a sobrecarregaram para boolcontinuar produzindo True/ Falsesaídas, mas na maioria dos casos, as operações booleanas deveriam ser feitas com or, não |. Os usos normais de |são bitwise-or ou set-union. Melhores exemplos de uso seriam algo como a = 0b1001; a |= 0b0010; print(bin(a))qual produz 0b1011.
ShadowRanger
3

É bit a bit ou. Digamos que temos 32 |= 10, as imagens 32 e 10 são binárias.

32 = 10 0000
10 = 00 1010

Agora porque | é ou, faça um bit a bit ou nos dois números

ou seja, 1 ou 0 -> 1, 0 ou 0 -> 0. Continue descendo a cadeia

10 0000 | 00 1010 = 10 1010.

Agora mude o binário em decimal, 10 1010 = 42.

Para | =, pense nos exemplos conhecidos x +=5,. Significa, x = x + 5,portanto, se tivermos x |= 5, isso significa x = x bitwiseor with 5.

memeKing
fonte
essa é a explicação que eu procurava, todo mundo falava sobre sets e bools mas ninguém mencionava seu uso com números.
Ankush Verma
O exemplo que você deu não é, 32 |= 10mas sim 32 | 10. Apenas para esclarecer isso para futuros leitores :)
atirador 71
@ sniper71 qual é o resultado de 32 | = 10
Futuro-Jim
2

Para fornecer um caso de uso (depois de passar algum tempo com as outras respostas):

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

Basicamente, anysem o curto-circuito: pode ser útil se você precisar processar cada item e registrar pelo menos um sucesso, etc.

Veja também as advertências nesta resposta

Scharfmn
fonte
1

Em Python, | = (ior) funciona como uma operação de união. como se x = 5 ex | = 5, então ambos os valores serão primeiro convertidos em valor binário, então a operação de união será executada e obteremos a resposta 5.

aanchal.s
fonte