Que fait | = (ior) en Python?

112

Google ne me laisse pas effectuer de recherche |=, j'ai donc du mal à trouver la documentation pertinente. Quelqu'un sait-il?

Sean W.
la source
5
Je pense qu'il est pertinent de souligner, comme dans la réponse de sunny ci-dessous, qui |est également utilisé comme opérateur d'union d'ensemble
TallChuck
10
en 2019, Google vous permettra de rechercher` | = `! :-)
rbennell

Réponses:

46

|=effectue une opération en place + entre des paires d'objets. En particulier, entre:

Dans la plupart des cas, il est lié à l' |opérateur. Voir les exemples ci-dessous.

Ensembles

Par exemple, l'union de deux ensembles affectés s1et s2partager les expressions équivalentes suivantes:

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

où la valeur finale de s1est équivalente soit par:

  1. une opération OR assignée
  2. une opération OU en place
  3. une opération OR en place via une méthode spéciale ++

Exemple

Ici, nous appliquons OR ( |) et OR ( |=) en place aux ensembles :

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

Dictionnaires

Dans Python 3.9+ , de nouveaux opérateurs merge ( |) et update ( |=) sont proposés entre les dictionnaires. Remarque: ce ne sont pas les mêmes que les opérateurs d'ensemble mentionnés ci-dessus.

Opérations données entre deux dicts assignés d1et d2:

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

d1est équivalent via:

  1. une opération de droit de fusion assignée
  2. une opération de fusion sur place (mise à jour); équivalent àd1.update(d2)

Exemple

Ici, nous appliquons merge ( |) et update ( |=) aux dictionnaires :

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

Compteurs

Le collections.Counterest lié à une structure de données mathématique appelée multiset (mset). Il s'agit essentiellement d'un dict de paires clé-valeur (objet, multiplicité).

Opérations données entre deux compteurs assignés c1et c2:

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

c1est équivalent via:

  1. une opération syndicale assignée
  2. une opération syndicale en place

Une union de multisets contient les multiplicités maximales par entrée. Notez que cela ne se comporte pas de la même manière qu'entre deux ensembles ou entre deux dictionnaires réguliers.

Exemple

Ici, nous appliquons union ( |) et l'union sur place ( |=) aux compteurs :

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

Nombres

Enfin, vous pouvez faire des calculs binaires.

Opérations données entre deux numéros attribués n1et n2:

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

n1est équivalent via:

  1. une opération OR au niveau du bit attribuée
  2. une opération OR au niveau du bit sur place

Exemple

Ici, nous appliquons le OR bit à bit ( |) et le OR bit à la place ( |=) aux nombres :

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

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

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

La revue

Cette section passe brièvement en revue quelques mathématiques au niveau du bit. Dans le cas le plus simple, l'opération OR au niveau du bit compare deux bits binaires. Il retournera toujours 1sauf lorsque les deux bits le sont 0.

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

Nous étendons maintenant cette idée au-delà des nombres binaires. Étant donné deux nombres entiers quelconques (sans composantes fractionnaires), nous appliquons le OU au niveau du bit et obtenons un résultat intégral:

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

Comment? En général, les opérations au niveau du bit suivent certaines "règles":

  1. comparer en interne les équivalents binaires
  2. appliquer l'opération
  3. renvoie le résultat comme le type donné

Appliquons ces règles à nos entiers réguliers ci-dessus.

(1) Comparez les équivalents binaires, vus ici sous forme de chaînes ( 0bdésigne le binaire):

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

(2) Appliquez une opération OR au niveau du bit à chaque colonne ( 0lorsque les deux sont 0, sinon 1):

01010
10000
-----
11010

(3) Renvoie le résultat dans le type donné, par exemple base 10, décimal:

>>> int(0b11010)
26

La comparaison binaire interne signifie que nous pouvons appliquer ce dernier à des entiers dans n'importe quelle base, par exemple hex et octal:

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

Voir également

+ L'opérateur OR au niveau du bit en place ne peut pas être appliqué aux littéraux; affecter des objets aux noms.

++ Les méthodes spéciales renvoient les mêmes opérations que leurs opérateurs correspondants.

pylang
la source
2
Pour être parfaitement clair, j'ajouterais à la démonstration qu'après avoir fait l'assignation régulière (x = x | y) l'id (x) a changé car c'est un nouvel objet, tandis que | = garde le même id car c'est le x d'origine qui est modifié, d'où le nom «inplace».
Florimond
1
Cela devrait être la meilleure réponse - c'est la plus exhaustive.
Nick
Dans la section des nombres, vous prétendez que la deuxième instruction effectue une opération sur place. Je pense que ce n'est pas vrai, car les ints ne sont pas mutables en Python.
Asocia
106

En Python, et dans de nombreux autres langages de programmation, se |trouve l' opération OR au niveau du bit . |=est à |tel quel, c'est- +=à +-dire une combinaison d'opération et d'affectation.

Donc var |= valuec'est court pour var = var | value.

Un cas d'utilisation courant consiste à fusionner deux ensembles:

>>> a = {1,2}; a |= {3,4}; print(a)
{1, 2, 3, 4}
Daniel Stutzbach
la source
21
Pouvez-vous donner un exemple?
minéraux
J'ai donné un cas d'utilisation que j'ai rencontré ci
scharfmn
53

Lorsqu'il est utilisé avec des ensembles, il effectue une opération d'union.

ensoleillé
la source
1
Je lisais du code et le a |=été utilisé dans un contexte défini, et ce n'est que lorsque j'ai déconné et compris que j'ai remarqué que cette réponse était ici aussi
TallChuck
41

Il s'agit simplement d'une opération OR entre la variable courante et l'autre. Étant T=Trueet F=False, voyez la sortie graphiquement:

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

Par exemple:

>>> r=True
>>> r|=False
>>> r
True
>>> r=False
>>> r|=False
>>> r
False
>>> r|=True
>>> r
True
fedorqui 'Alors arrêtez de nuire'
la source
7
Cela donne une sorte d'impression déformée de l'opérateur; |est un opérateur bit à bit pour les entiers, pas spécifiquement un opérateur booléen, et pour tout autre chose que bools, il ne produira Trueni ne sortira réellement False. boolest une sous-classe de int, et pour être gentil, ils l'ont surchargée pour boolcontinuer à produire True/ Falsesorties, mais dans la plupart des cas, les opérations booléennes devraient être effectuées avec or, pas |. Les utilisations normales de |sont bitwise-or, ou set-union. De meilleurs exemples d'utilisation seraient quelque chose comme a = 0b1001; a |= 0b0010; print(bin(a))qui produit 0b1011.
ShadowRanger
3

C'est au niveau du bit ou. Disons que nous avons 32 |= 10, les images 32 et 10 sont binaires.

32 = 10 0000
10 = 00 1010

Maintenant parce que | est ou, faites un bit ou sur les deux nombres

c'est-à-dire 1 ou 0 -> 1, 0 ou 0 -> 0. Continuez le long de la chaîne

10 0000 | 00 1010 = 10 1010.

Maintenant changez le binaire en décimal, 10 1010 = 42.

Pour | =, pensez des exemples connus, x +=5. Cela signifie x = x + 5,donc si nous avons x |= 5, cela signifie x = x bitwiseor with 5.

memeKing
la source
c'est l'explication que je cherchais, tout le monde a parlé d'ensembles et de booléens mais personne n'a mentionné son utilisation avec des nombres.
Ankush Verma
L'exemple que vous avez donné n'est pas 32 |= 10mais plutôt 32 | 10. Juste pour clarifier cela pour les futurs lecteurs :)
sniper71
@ sniper71 quel est le résultat de 32 | = 10
Future-Jim
2

Pour donner un cas d'utilisation (après avoir passé du temps avec les autres réponses):

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

Fondamentalement, anysans le court-circuit: cela peut être utile si vous devez traiter chaque élément et enregistrer au moins un succès, etc.

Voir aussi les mises en garde dans cette réponse

scharfmn
la source
1

En Python, | = (ior) fonctionne comme une opération d'union. comme si x = 5 et x | = 5, la valeur sera d'abord convertie en valeur binaire, puis l'opération d'union s'effectuera et nous obtenons la réponse 5.

aanchal.s
la source