Co robi | = (ior) w Pythonie?

112

Google nie pozwala mi szukać, |=więc mam problem ze znalezieniem odpowiedniej dokumentacji. Czy ktoś wie?

Sean W.
źródło
5
Myślę, że warto zwrócić uwagę, jak w poniższej odpowiedzi Sunny, która |jest również używana jako operator set union
TallChuck
10
w 2019 roku Google pozwoli Ci wyszukiwać` | = `! :-)
rbennell

Odpowiedzi:

46

|=wykonuje operację w miejscu + między parami obiektów. W szczególności między:

W większości przypadków jest to związane z |operatorem. Zobacz przykłady poniżej.

Zestawy

Na przykład połączenie dwóch przypisanych zestawów s1i s2współdzielenie następujących równoważnych wyrażeń:

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

gdzie końcowa wartość s1jest równoważna albo przez:

  1. przypisana operacja OR
  2. operacja w miejscu OR
  3. operacja OR w miejscu za pomocą specjalnej metody ++

Przykład

Tutaj stosujemy OR ( |) i inplace OR ( |=) do zestawów :

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

Słowniki

W Pythonie 3.9+ nowe operatory merge ( |) i update ( |=) są proponowane między słownikami. Uwaga: to nie to samo, co operatory zbioru wymienione powyżej.

Biorąc pod uwagę operacje między dwoma przypisanymi dyktami d1i d2:

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

gdzie d1odpowiada poprzez:

  1. przypisana operacja z prawem scalania
  2. operacja typu „merge-right” (aktualizacja) w miejscu; równoważnyd1.update(d2)

Przykład

Tutaj stosujemy merge ( |) i update ( |=) do dykt :

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

Liczniki

collections.CounterDotyczy matematycznego datastructure zwanego multiset (MSET). Jest to w zasadzie dyktando par klucz-wartość (obiekt, wielokrotność).

Dane operacje między dwoma przypisanymi licznikami c1i c2:

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

gdzie c1odpowiada poprzez:

  1. przypisana operacja związkowa
  2. operacja związkowa na miejscu

Unia multisets zawiera krotności maksymalnych na wejściu. Uwaga, nie zachowuje się to tak samo, jak między dwoma zestawami lub między dwoma zwykłymi dyktami.

Przykład

Tutaj stosujemy union ( |) i in-place union ( |=) do 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})

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

Liczby

Na koniec możesz wykonywać obliczenia binarne.

Biorąc pod uwagę operacje między dwoma przypisanymi numerami n1i n2:

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

gdzie n1odpowiada poprzez:

  1. przypisana bitowa operacja OR
  2. bitowa operacja OR w miejscu

Przykład

Tutaj stosujemy bitowe OR ( |) i lokalne bitowe OR ( |=) do liczb :

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

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

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

Przejrzeć

W tej sekcji krótko omówiono matematykę bitową. W najprostszym przypadku operacja bitowa OR porównuje dwa bity binarne. Zawsze zwróci, 1z wyjątkiem sytuacji, gdy oba bity są 0.

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

Teraz rozszerzymy ten pomysł poza liczby binarne. Biorąc pod uwagę dowolne dwie liczby całkowite (bez składników ułamkowych), stosujemy bitowe OR i otrzymujemy wynik całkowity:

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

W jaki sposób? Ogólnie rzecz biorąc, operacje bitowe podlegają pewnym „regułom”:

  1. wewnętrznie porównaj odpowiedniki binarne
  2. zastosować operację
  3. zwraca wynik jako podany typ

Zastosujmy te reguły do ​​naszych zwykłych liczb całkowitych powyżej.

(1) Porównaj odpowiedniki binarne, widziane tutaj jako ciągi ( 0boznacza binarne):

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

(2) Zastosuj bitową operację OR do każdej kolumny ( 0gdy obie są 0, w przeciwnym razie 1):

01010
10000
-----
11010

(3) Zwróć wynik w podanym typie, np. Podstawa 10, dziesiętna:

>>> int(0b11010)
26

Wewnętrzne porównanie binarne oznacza, że ​​możemy zastosować to drugie do liczb całkowitych o dowolnej podstawie, np. Szesnastkowej i ósemkowej:

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

Zobacz też

+ W miejscu bitowego operatora OR nie można zastosować do literałów; przypisywać obiekty do nazw.

++ Metody specjalne zwracają te same operacje, co odpowiadające im operatory.

pylang
źródło
2
Żeby było jasne, dodałbym do demonstracji, że po wykonaniu zwykłego przypisania (x = x | y) id (x) zmieniło się, ponieważ jest to nowy obiekt, podczas gdy | = zachowuje ten sam identyfikator, ponieważ jest to oryginalne x, które jest modyfikowany, stąd nazwa „inplace”.
Florimond
1
To powinna być najlepsza odpowiedź - jest najbardziej wyczerpująca.
Nick
W sekcji liczbowej twierdzisz, że druga instrukcja wykonuje operacje na miejscu. Myślę, że to nieprawda, ponieważ intnie można ich zmieniać w Pythonie.
Asocia
106

W Pythonie i wielu innych językach programowania |jest operacja bitowa-OR . |=jest |tak, jak +=jest +, tj. połączenie operacji i przypisania.

Więc var |= valuejest skrótem od var = var | value.

Typowym przypadkiem użycia jest połączenie dwóch zestawów:

>>> a = {1,2}; a |= {3,4}; print(a)
{1, 2, 3, 4}
Daniel Stutzbach
źródło
21
Czy możesz podać przykład?
minerały
Podałem
53

W przypadku użycia z zestawami wykonuje operację sumowania.

słoneczny
źródło
1
Czytałem kod i |=został użyty w określonym kontekście i dopiero gdy się pogubiłem i zorientowałem się, że zauważyłem, że ta odpowiedź również jest tutaj
TallChuck
41

To jest po prostu operacja OR między bieżącą zmienną a drugą. Będąc T=Truei F=False, zobacz dane wyjściowe graficznie:

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

Na przykład:

>>> r=True
>>> r|=False
>>> r
True
>>> r=False
>>> r|=False
>>> r
False
>>> r|=True
>>> r
True
fedorqui 'SO przestań szkodzić'
źródło
7
Daje to coś w rodzaju wypaczonego wrażenia operatora; |jest operatorem bitowym lub dla liczb całkowitych, a nie operatorem logicznym, a dla czegokolwiek innego niż bools, w rzeczywistości nie generuje Trueani nie wyświetla Falsewyników. booljest podklasą inti żeby być miłym, przeładowali ją, boolaby kontynuować produkcję True/ Falsewyjścia, ale w większości przypadków operacje logiczne powinny być wykonywane za pomocą or, nie |. Normalne zastosowania |to to bitowa lub set-union. Lepszymi przykładami użycia byłoby coś, a = 0b1001; a |= 0b0010; print(bin(a))co produkuje 0b1011.
ShadowRanger,
3

Jest bitowy lub. Powiedzmy, że mamy 32 |= 10, obrazki 32 i 10 są binarne.

32 = 10 0000
10 = 00 1010

Teraz, ponieważ | jest lub, wykonaj bitowo lub na dwóch liczbach

tj. 1 lub 0 -> 1, 0 lub 0 -> 0. Kontynuuj w dół łańcucha

10 0000 | 00 1010 = 10 1010.

Teraz zmień liczbę dwójkową na dziesiętną, 10 1010 = 42.

Dla | =, pomyślcie o znanych przykładach x +=5. Oznacza to, x = x + 5,że jeśli mamy x |= 5, to znaczy x = x bitwiseor with 5.

memeKing
źródło
to jest wyjaśnienie, którego szukałem, wszyscy mówili o zestawach i boolach, ale nikt nie wspomniał o ich zastosowaniu z liczbami.
Ankush Verma
Przykład, który podałeś, nie jest, 32 |= 10ale raczej 32 | 10.
Żeby
@ sniper71 jaki jest wynik 32 | = 10
Future-Jim
2

Aby podać przypadek użycia (po spędzeniu czasu z innymi odpowiedziami):

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

Zasadniczo anybez zwarcia: może być przydatne, jeśli musisz przetworzyć każdy element i odnotować co najmniej jeden sukces itp.

Zobacz także zastrzeżenia w tej odpowiedzi

scharfmn
źródło
1

W Pythonie, | = (ior) działa jak operacja na sumieniu. na przykład jeśli x = 5 i x | = 5, obie wartości zostaną najpierw przekonwertowane na wartość binarną, a następnie zostanie wykonana operacja sumowania i otrzymamy odpowiedź 5.

aanchal.s
źródło