Що робить | = (ior) у Python?


112

Google не дозволить мені здійснювати пошук, |=тому у мене виникають проблеми з пошуку відповідної документації. Хтось знає?


5
Я думаю, що це доречно зазначити, як у відповіді сонячного нижче, що |також використовується як встановлений оператор спілки
TallChuck

10
у 2019 році Google дозволить вам шукати "| =`! :-)
rbennell

Відповіді:


45

|=виконує операцію на місці + між парами об'єктів. Зокрема, між:

У більшості випадків це пов’язано з |оператором. Дивіться приклади нижче.

Набори

Наприклад, об'єднання двох присвоєних множин 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 ( |=) пропонуються між словниками. Примітка: вони не збігаються із зазначеними вище операторами.

Дані операції між двома призначеними диктами d1та d2:

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

де d1еквівалентно через:

  1. призначена операція право злиття
  2. операція на місці злиття (оновлення); дорівнюєd1.update(d2)

Приклад

Тут ми застосовуємо merge ( |) та update ( |=) до диктів :

>>> 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 ( |=) до лічильників :

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) id (x) змінився, оскільки це новий об'єкт, тоді як | = зберігає той самий ідентифікатор, тому що це вихідний x, модифікується, звідси і назва "inplace".
Флорімон

1
Це має бути головна відповідь - це найвичерпніше.
Нік

У розділі цифр ви заявляєте, що друге висловлювання працює на місці. Я думаю, що це неправда, оскільки ints не змінюються в Python.
Асоція

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

7
Це створює якесь викривлене враження від оператора; |є побітним оператором або оператором для цілих чисел, не конкретно булевим оператором, і для нічого іншого, крім bools, він фактично не виробляє Trueі не Falseвиводить. boolце підклас int, і, що було б добре, вони перевантажили його, boolщоб продовжувати виробляти True/ Falseвиводити, але в більшості випадків булеві операції слід робити or, а не |. Звичайні способи використання |є бітовими або встановленими об'єднаннями. Кращими прикладами використання було б щось таке, a = 0b1001; a |= 0b0010; print(bin(a))що створює 0b1011.
ShadowRanger


3

Це побіжно або. Скажімо, маємо 32 |= 10, малюнок 32 і 10 є двійковим.

32 = 10 0000
10 = 00 1010

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

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

10 0000 | 00 1010 = 10 1010.

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

Для | =, думати про відомих прикладах x +=5. Це означає, що x = x + 5,якщо у нас є x |= 5, це означає x = x bitwiseor with 5.


це пояснення, яке я шукав, всі говорили про набори та булі, але ніхто не згадував про його використання із цифрами.
Анкуш Верма

Приклад, який ви подали, не є, 32 |= 10а скоріше 32 | 10. Просто для уточнення цього для майбутніх читачів :)
sniper71

@ sniper71, що результат 32 | = 10
Майбутнє-Джим

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без короткого замикання: може бути корисним, якщо вам потрібно обробити кожен елемент і записати хоча б один успіх тощо.

Дивіться також застереження в цій відповіді


1

У Python, | = (ior) працює як операція об'єднання. наприклад, якщо x = 5 і x | = 5, то обидва значення спочатку перетворяться у двійкове значення, потім виконується операція об'єднання, і ми отримуємо відповідь 5.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.