Cosa fa | = (ior) in Python?


112

Google non mi consente di eseguire ricerche, |=quindi ho problemi a trovare la documentazione pertinente. Qualcuno sa?


5
Penso che sia rilevante sottolineare, come nella risposta di Sunny di seguito, che |viene utilizzato anche come operatore di unione dell'insieme
TallChuck

10
nel 2019 Google ti permetterà di cercare` | = `! :-)
rbennell

Risposte:


45

|=esegue un'operazione sul posto + tra coppie di oggetti. In particolare, tra:

Nella maggior parte dei casi, è correlato |all'operatore. Vedi esempi di seguito.

Imposta

Ad esempio, l'unione di due set assegnati s1e s2condividere le seguenti espressioni equivalenti:

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

dove il valore finale di s1è equivalente o da:

  1. un'operazione OR assegnata
  2. un'operazione OR sul posto
  3. un'operazione OR sul posto tramite un metodo speciale ++

Esempio

Qui applichiamo OR ( |) e l'inplace OR ( |=) agli insiemi :

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

dizionari

In Python 3.9+ , vengono proposti nuovi operatori merge ( |) e update ( |=) tra i dizionari. Nota: questi non sono gli stessi degli operatori di gruppo menzionati sopra.

Date operazioni tra due dict assegnati d1e d2:

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

dove d1è equivalente tramite:

  1. un'operazione di unione a destra assegnata
  2. un'operazione sul posto di unione dei diritti (aggiornamento); equivalente ad1.update(d2)

Esempio

Qui applichiamo merge ( |) e update ( |=) ai dict :

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

contatori

Il collections.Counterè legato a un datastructure matematico chiamato un multiset (mset). È fondamentalmente un dettato di coppie chiave-valore (oggetto, molteplicità).

Date operazioni tra due contatori assegnati c1e c2:

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

dove c1è equivalente tramite:

  1. un'operazione sindacale assegnata
  2. un'operazione sindacale sul posto

Un'unione di multinsiemi contiene i massimi molteplicità per ogni linea. Nota, questo non si comporta allo stesso modo tra due set o tra due dict regolari.

Esempio

Qui applichiamo union ( |) e l'unione sul posto ( |=) ai contatori :

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

Numeri

Infine, puoi fare matematica binaria.

Date operazioni tra due numeri assegnati n1e n2:

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

dove n1è equivalente tramite:

  1. un'operazione OR bit per bit assegnata
  2. un'operazione OR bit per bit sul posto

Esempio

Qui applichiamo OR bit per bit ( |) e OR bit per bit ( ) sul posto |=ai numeri :

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

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

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

Revisione

Questa sezione esamina brevemente alcuni calcoli matematici bit per bit. Nel caso più semplice, l'operazione OR bit per bit confronta due bit binari. Tornerà sempre 1tranne quando entrambi i bit sono 0.

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

Ora estendiamo questa idea oltre i numeri binari. Dati due numeri interi (privi di componenti frazionarie), applichiamo l'OR bit per bit e otteniamo un risultato integrale:

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

Come? In generale, le operazioni bit per bit seguono alcune "regole":

  1. confronta internamente gli equivalenti binari
  2. applicare l'operazione
  3. restituisce il risultato come il tipo specificato

Applichiamo queste regole ai nostri numeri interi regolari sopra.

(1) Confronta gli equivalenti binari, visti qui come stringhe ( 0bdenota binario):

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

(2) Applicare un'operazione OR bit per bit a ciascuna colonna ( 0quando entrambi lo sono 0, altrimenti 1):

01010
10000
-----
11010

(3) Restituisce il risultato nel tipo dato, ad esempio in base 10, decimale:

>>> int(0b11010)
26

Il confronto binario interno significa che possiamo applicare quest'ultimo a numeri interi in qualsiasi base, ad esempio esadecimale e ottale:

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

Guarda anche

+ L'operatore OR bit per bit sul posto non può essere applicato ai letterali; assegna oggetti ai nomi.

++ I metodi speciali restituiscono le stesse operazioni dei rispettivi operatori.


2
Per essere perfettamente chiaro, aggiungerei alla dimostrazione che dopo aver eseguito l'assegnazione regolare (x = x | y) l'id (x) è cambiato perché è un nuovo oggetto, mentre | = mantiene lo stesso id perché è la x originale che viene modificato, da cui il nome "inplace".
Florimond

1
Questa dovrebbe essere la risposta migliore: è la più esaustiva.
Nick

Nella sezione dei numeri, stai affermando che la seconda affermazione esegue un'operazione sul posto. Penso che non sia vero, poiché le ints non sono modificabili in Python.
Asocia

106

In Python, e in molti altri linguaggi di programmazione, |è l' operazione OR bit per bit . |=è |come +=è +, cioè una combinazione di operazione e assegnazione.

Quindi var |= valueè breve per var = var | value.

Un caso d'uso comune consiste nell'unire due set:

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

21
Puoi fornire un esempio?
minerali

Ho fornito un caso d'uso che ho riscontrato di seguito
scharfmn

53

Quando viene utilizzato con i set, esegue un'operazione di unione.


1
Stavo leggendo del codice ed è |=stato utilizzato nel contesto impostato, e non è stato fino a quando non ho combinato un pasticcio e ho capito che ho notato che anche questa risposta era qui
TallChuck

41

Questa è solo un'operazione OR tra la variabile corrente e l'altra. Essere T=Truee F=False, vedere l'output graficamente:

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

Per esempio:

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

7
Questo dà una sorta di impressione distorta dell'operatore; |è un operatore bit per bit o per interi, non specificamente un operatore booleano, e per qualsiasi cosa diversa da bools, in realtà non produrrà TrueFalserestituirà. boolè una sottoclasse di int, e per essere carini, l'hanno sovraccaricata per boolcontinuare a produrre True/ Falseoutput, ma nella maggior parte dei casi, le operazioni booleane dovrebbero essere fatte con or, non |. Gli usi normali per |sono bitwise-or, o set-union. Migliori esempi di utilizzo sarebbero qualcosa di simile a = 0b1001; a |= 0b0010; print(bin(a))che produce 0b1011.
ShadowRanger


3

È bit a bit o. Diciamo che abbiamo 32 |= 10, l'immagine 32 e 10 è binaria.

32 = 10 0000
10 = 00 1010

Ora perché | è o, fai un bit per bit o sui due numeri

cioè 1 o 0 -> 1, 0 o 0 -> 0. Continua questo lungo la catena

10 0000 | 00 1010 = 10 1010.

Ora cambia il binario in un decimale, 10 1010 = 42.

Per | =, pensare a degli esempi noti, x +=5. Significa x = x + 5,quindi se abbiamo x |= 5, significa x = x bitwiseor with 5.


questa è la spiegazione che cercavo, tutti parlavano di set e bool ma nessuno ne menzionava l'uso con i numeri.
Ankush Verma

L'esempio che hai fornito non è 32 |= 10ma piuttosto 32 | 10. Giusto per chiarire questo ai futuri lettori :)
sniper71

@ sniper71 qual è il risultato di 32 | = 10
Future-Jim

2

Per fornire un caso d'uso (dopo aver trascorso del tempo con le altre risposte):

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

Fondamentalmente any senza il cortocircuito: potrebbe essere utile se devi elaborare ogni elemento e registrare almeno un successo ecc.

Vedi anche le avvertenze in questa risposta


1

In Python, | = (ior) funziona come un'operazione di unione. come se x = 5 ex | = 5, entrambi i valori verranno prima convertiti in valore binario, quindi verrà eseguita l'operazione di unione e otterremo la risposta 5.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.