Что | = (ior) делает в Python?

112

Google не разрешает мне искать, |=поэтому у меня проблемы с поиском соответствующей документации. Кто-нибудь знает?

Шон В.
источник
5
Я думаю, уместно указать, как в солнечном ответе ниже, который |также используется в качестве оператора set union
TallChuck
10
в 2019 Google позволит вам искать` | = `! :-)
rbennell

Ответы:

47

|=выполняет операцию + на месте между парами объектов. В частности, между:

В большинстве случаев это связано с |оператором. См. Примеры ниже.

Наборы

Например, объединение двух присвоенных наборов s1и s2общих следующих эквивалентных выражений:

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

где окончательное значение s1эквивалентно либо:

  1. назначенная операция ИЛИ
  2. операция ИЛИ на месте
  3. операция ИЛИ на месте с помощью специального метода ++

пример

Здесь мы применяем OR ( |) и inplace OR ( |=) к множествам :

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

Словари

В Python 3.9+ между словарями предлагаются новые операторы merge ( |) и update ( |=). Примечание: это не то же самое, что и операторы множества, упомянутые выше.

Данные операции между двумя назначенными dicts d1и d2:

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

где d1эквивалентно через:

  1. назначенная операция слияния-права
  2. операция слияния (обновления) на месте; эквивалентноd1.update(d2)

пример

Здесь мы применяем merge ( |) и update ( |=) к 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}

Счетчики

Это collections.Counterсвязано с математической структурой данных, называемой мультимножеством (mset). Это в основном набор пар ключ-значение (объект, множественность).

Данные операции между двумя назначенными счетчиками c1и c2:

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

где c1эквивалентно через:

  1. назначенная операция объединения
  2. операция объединения на месте

Объединение мультимножеств содержит максимальные кратности на запись. Обратите внимание, это не ведет себя так же, как между двумя наборами или между двумя обычными диктовками.

пример

Здесь мы применяем union ( |) и in-place union ( |=) к 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})

Числа

Наконец, вы можете заниматься двоичной математикой.

Данные операции между двумя присвоенными номерами n1и n2:

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

где n1эквивалентно через:

  1. назначенная побитовая операция ИЛИ
  2. побитовая операция ИЛИ на месте

пример

Здесь мы применяем поразрядное ИЛИ ( |) и на месте поразрядное ИЛИ ( |=) к числам :

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

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

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

Обзор

В этом разделе кратко рассматривается поразрядная математика. В простейшем случае побитовая операция ИЛИ сравнивает два двоичных бита. Он всегда будет возвращаться, 1кроме случаев, когда оба бита верны 0.

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

Теперь мы расширим эту идею за пределы двоичных чисел. Для любых двух целых чисел (без дробных компонентов) мы применяем побитовое ИЛИ и получаем целочисленный результат:

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

Как? В целом побитовые операции подчиняются некоторым «правилам»:

  1. внутреннее сравнение двоичных эквивалентов
  2. применить операцию
  3. вернуть результат как заданный тип

Давайте применим эти правила к нашим обычным целым числам, указанным выше.

(1) Сравните двоичные эквиваленты, представленные здесь как строки ( 0bобозначает двоичные):

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

(2) Примените побитовую операцию ИЛИ к каждому столбцу ( 0если есть оба 0, иначе 1):

01010
10000
-----
11010

(3) Вернуть результат в заданном типе, например, с десятичным основанием 10:

>>> int(0b11010)
26

Внутреннее двоичное сравнение означает, что мы можем применить последнее к целым числам в любом основании, например, шестнадцатеричном и восьмеричном:

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

Смотрите также

+ Оператор поразрядного ИЛИ на месте не может применяться к литералам; назначать объекты именам.

++ Специальные методы возвращают те же операции, что и соответствующие им операторы.

пиланг
источник
2
Для большей ясности я бы добавил к демонстрации, что после выполнения обычного присвоения (x = x | y) идентификатор (x) изменился, потому что это новый объект, а | = сохраняет тот же идентификатор, потому что это исходный x, который изменяется, отсюда и название "inplace".
Флоримонд,
1
Это должен быть главный ответ - он самый исчерпывающий.
Ник
В разделе чисел вы утверждаете, что второй оператор выполняет операцию на месте. Я думаю, что это неправда, поскольку ints не изменяются в Python.
Asocia
106

В Python и многих других языках программирования |используется побитовое ИЛИ . |=это |как +=есть +, то есть комбинация операции и присвоения.

Так var |= valueкоротка для var = var | value.

Типичный вариант использования - объединение двух наборов:

>>> a = {1,2}; a |= {3,4}; print(a)
{1, 2, 3, 4}
Даниэль Штутцбах
источник
21
Не могли бы вы привести пример?
минералы
Приведу
53

При использовании с наборами выполняет операцию объединения.

солнечно
источник
1
Я читал какой-то код, и |=он использовался в заданном контексте, и только когда я запутался и понял это, я заметил, что этот ответ тоже здесь
TallChuck
41

Это просто операция ИЛИ между текущей переменной и другой. Будучи T=Trueи F=False, просмотрите результат графически:

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

Например:

>>> r=True
>>> r|=False
>>> r
True
>>> r=False
>>> r|=False
>>> r
False
>>> r|=True
>>> r
True
fedorqui 'ТАК, хватит вредить'
источник
7
Это создает своего рода искаженное впечатление об операторе; |является побитовым оператором ИЛИ для целых чисел, а не конкретно логическим оператором, и для чего-либо, кроме bools, он фактически не производит Trueили не Falseвыводит. boolявляется подклассом int, и, чтобы быть приятным, они перегружали его, boolчтобы продолжать производить True/ Falseвыводить, но в большинстве случаев логические операции должны выполняться с помощью or, а не |. Обычное использование for |- побитовое или или множественное объединение. Лучшими примерами использования были бы что-то вроде того, a = 0b1001; a |= 0b0010; print(bin(a))что производит 0b1011.
ShadowRanger 09
3

Побитовое или. Допустим, у нас есть 32 |= 10изображения 32 и 10 в двоичном формате.

32 = 10 0000
10 = 00 1010

Теперь, потому что | или, побитовое или на двух числах

т.е. 1 или 0 -> 1, 0 или 0 -> 0. Продолжайте это вниз по цепочке

10 0000 | 00 1010 = 10 1010.

Теперь измените двоичный код на десятичный, 10 10 10 = 42.

Для | =, думать о известных примерах x +=5. Значит, x = x + 5,значит, если есть x |= 5, значит x = x bitwiseor with 5.

мемКинг
источник
это объяснение, которое я искал, все говорили о наборах и логических значениях, но никто не упоминал о его использовании с числами.
Анкуш Верма
Приведенный вами пример не 32 |= 10а точнее 32 | 10. Просто чтобы прояснить это для будущих читателей :)
sniper71
@ sniper71 каков результат 32 | = 10
Future-Jim
2

В Python | = (ior) работает как операция объединения. например, если x = 5 и x | = 5, то оба значения сначала будут преобразованы в двоичное значение, затем будет выполнена операция объединения, и мы получим ответ 5.

aanchal.s
источник
2

Чтобы дать пример использования (потратив время на другие ответы):

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

В основном anyбез короткого замыкания: может быть полезно, если вам нужно обработать каждый элемент и записать хотя бы один успех и т. Д.

См. Также предостережения в этом ответе

Scharfmn
источник