Python: 按位或运算符(Bitwise OR)

2022-12-18 11:59:47 浏览数 (1)

文章背景: 最近在学习Qt5的QFileDialog(提供选择文件或目录的GUI的对话框),有一段代码用到了按位或运算符(|=),

代码语言:javascript复制
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog

一开始没看懂按位或运算符|=在这段代码中起到的作用,查阅相关资料后,才明白这是为了不使用本地系统的文件对话框。QFileDialog.Options()提供了影响文件对话框样貌的各种选项,其中有个选项是QFileDialog.DontUseNativeDialog,其默认值是False。通过options |= QFileDialog.DontUseNativeDialog这句代码是为了更新选项中的这个默认值,也就是说,不使用本地系统的文件对话框。

本着举一反三的学习理念,接下来对按位或运算符进行系统的学习。

|= performs an in-place operation (原地运算符) between pairs of objects. In particular, between:

  • sets: a union operation
  • dicts: an update operation
  • counters: a union (of multisets) operation
  • numbers: a bitwise OR, binary operation In most cases, it is related to the | operator. See examples below. 1 Sets2 Dictionaries3 Counters4 Numbers
1 Sets

For example, the union of two assigned sets s1 and s2 share the following equivalent expressions:

代码语言:javascript复制
>>> s1 = s1 | s2                                # 1
>>> s1 |= s2                                      # 2
>>> s1.__ior__(s2)                              # 3

where the final value of s1 is equivalent either by:

  1. an assigned OR operation
  2. an in-place OR operation
  3. an in-place OR operation via special method 示例代码: s1 = {"a", "b", "c"} s2 = {"d", "e", "f"} s_or = s1 | s2 # OR, | print("s1: " str(s1)) # s1 is unchanged print("s_or: " str(s_or)) s1 |= s2 # In-place OR, |= print("s_in: " str(s1)) # s1 is reassigned s1: {'a', 'b', 'c'} s_or: {'d', 'e', 'c', 'a', 'b', 'f'} s_in: {'d', 'e', 'c', 'a', 'b', 'f'}
2 Dictionaries

In Python 3.9 , new merge (|) and update (|=) operators are proposed between dictionaries. Note: these are not the same as set operators mentioned above.

Given operations between two assigned dicts d1 and d2:

代码语言:javascript复制
>>> d1 = d1 | d2                               # 1
>>> d1 |= d2                                     # 2

where d1 is equivalent via:

  1. an assigned merge-right operation
  2. an in-place merge-right (update) operation; equivalent to d1.update(d2) 示例代码:
代码语言:javascript复制
d1 = {"a": 0, "b": 1, "c": 2}
d2 = {"c": 20, "d": 30}

d_merge = d1 | d2                  # Merge, |
print("d1: "   str(d1))            # d1 is unchanged
print("d_merge: "   str(d_merge))

d1 |= d2                           # Update, |=
print("d_updated: "   str(d1))     # d1 is updated
代码语言:javascript复制
d1: {'a': 0, 'b': 1, 'c': 2}
d_merge: {'a': 0, 'b': 1, 'c': 20, 'd': 30}
d_updated: {'a': 0, 'b': 1, 'c': 20, 'd': 30}
3 Counters

Counter是一个dict子类,主要是用来对你访问的对象的频率进行计数。

The collections.Counter is related to a mathematical datastructure called a multiset (mset). It is basically a dict of (object, multiplicity) key-value pairs.

Given operations between two assigned counters c1 and c2:

代码语言:javascript复制
>>> c1 = c1 | c2                                  # 1
>>> c1 |= c2                                        # 2

where c1 is equivalent via:

  1. an assigned union operation
  2. an in-place union operation

A union of multisets contains the maximum multiplicities per entry. Note, this does not behave the same way as between two sets or between two regular dicts.

示例代码:

代码语言:javascript复制
c1 = ct.Counter({2: 2, 3: 3})
c2 = ct.Counter({1: 1, 3: 5})

c_union = c1 | c2                  # Union, |
print("c1: "   str(c1))            # c1 is unchanged
print("c_union: "   str(c_union))

c1 |= c2                           # Update, |=
print("c_in: "   str(c1))
代码语言:javascript复制
c1: Counter({3: 3, 2: 2})
c_union: Counter({3: 5, 2: 2, 1: 1})
c_in: Counter({3: 5, 2: 2, 1: 1})
4 Numbers

Lastly, you can do binary math. 按位或运算,只要对应两个二进制位有一个为1时,结果就为1。

Given operations between two assigned numbers n1 and n2:

代码语言:javascript复制
>>> n1 = n1 | n2                               # 1
>>> n1 |= n2                                     # 2

where n1 is equivalent via:

  1. an assigned bitwise OR operation
  2. an in-place bitwise OR operation 示例代码:
代码语言:javascript复制
n1 = 0
n2 = 1

n_or = n1 | n2                       # Bitwise OR, |
print("n1: "   str(n1))              # n1 is unchanged
print("n_or: "   str(n_or))

n1 |= n2                             # In-place Bitwise OR, |=
print("n_in: "   str(n1))

参考资料:

[1] Qt的GUI设计与制作(https://its401.com/article/qq_38410730/80745231

[2] Python PyQt5 學習筆記(https://hackmd.io/@kaneyxx/HJdX8DXCr

[3] Options(https://doc.qt.io/qt-6/qfiledialog.html#Option-enum

[4] In-place Operators(https://docs.python.org/3/library/operator.html#in-place-operators

[5] Python 原地操作(https://www.gairuo.com/p/python-in-place

[6] What does |= (ior) do in Python?(https://stackoverflow.com/questions/3929278/what-does-ior-do-in-python

[7] Python的collections模块真的很好用(https://www.cainiaojc.com/note/qah574.html

[8] Python Counter - Python Collections Counter(https://www.digitalocean.com/community/tutorials/python-counter-python-collections-counter

[9] 一篇读懂Python中的位运算(https://www.cnblogs.com/Neeo/articles/10536202.html

0 人点赞