说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
Python 的按位运算(Bitwise Operations)只对整数有意义。 计算按位运算的结果,就相当于使用无穷多个二进制符号位对二的补码执行操作。位运算是按照数据在内存中的二进制位(Bit)进行的操作。
如果不想关注底层开发可跳过本内容,有需求时再来学习。
简单来说,位运算是把数字转换为机器语言,也就是二进制来进行计算的一种运算形式。我们的电脑电路设计都是基于二进制的,所以在二进制层面效率很高。通常位运算多用在对程序效率要求很高的场景,它可以获得更高的性能,它一般用于底层开发(算法设计、驱动、图像处理、单片机等)。但是缺点也很明显,理解起来稍显复杂,不够直观,我们日常的数据分析、Web 开发等场景使用较少。
想理解二进制整数的存储需要了解定点数的3种表示法:原码、反码和补码。这里总结如下:
原、反、补码小结:
优缺点:
整数的按位操作表如下:
运算 | 结果 | 备注 |
---|---|---|
x ∣ y |
x 和 y 按位 或 | (4) |
x ^ y |
x 和 y 按位 异或 | (4) |
x & y |
x 和 y 按位 与 | (4) |
x << n |
x 左移 n 位 | (1)(2) |
x >> n |
x 右移 n 位 | (1)(3) |
~x |
x 逐位取反 | - |
注释:
ValueError
。pow(2, n)
。pow(2, n)
,作向下取整除法。1 + max(x.bit_length(), y.bit_length()
) 或以上)执行这些计算就足以获得相当于有无数个符号位时的同样结果。Python中的按位运算规则如下表所示:
运算符 | 描述 |
---|---|
& |
按位与运算符,参与运算的两个值,如果相应位都为1,则该位的结果为1,否则为0 |
^ |
按位异或运算符,当两个对应的二进位相异时,结果为1 |
~ |
按位取反运算符,对数据的每个二进制位取反,即把1变为0,把0变为1 |
∣ |
按位或运算,只要对应两个二进制位有一个为1时,结果就为1 |
<< |
左移动运算符:运算数的各二进制位全部左移若干位,由 << 右边的数字指定了移动的位数,高位丢弃,低位补0 |
>> |
右移动运算符:把 >> 左边的运算数的各二进制位全部右移若干位,>> 右边的数字指定了移动的位数 |
#正数最高位补1,负数补0,两个操作数一样长
# 3 的二进制
bin(3)[2:].zfill(len(bin(5)[2:]))
# '011'
# 5 的二进制
bin(5)[2:]
# '101'
# 与,都为1时为1,算得: 001
3 & 5
# 1
# 或,有一个为1时为1,算得: 111
3 | 5
# 7
# 验证二进制 111 是 7
0b111
# 7
布尔类型是一整型的子集,也可以支持按位运算,实现或与非等逻辑运算。
True & False
# False
1 > 2 | 1<2
# False
1 > 2 & 1<2
# True
要自定义 Python 的位运算符的行为,必须定义一个类,然后在其中实现相应的魔术方法(特殊方法)。同时,不能为现有类型重新定义按位运算符的行为。运算符重载只能在新数据类型上进行。
下面是让您重载按位运算符的特殊方法的快速汇总:
# 特殊方法及对应的表达式
.__and__(self, value) # instance & value
.__rand__(self, value) # value & instance
.__iand__(self, value) # instance &= value
.__or__(self, value) # instance | value
.__ror__(self, value) # value | instance
.__ior__(self, value) # instance |= value
.__xor__(self, value) # instance ^ value
.__rxor__(self, value) # value ^ instance
.__ixor__(self, value) # instance ^= value
.__invert__(self) # ~instance
.__lshift__(self, value) # instance << value
.__rlshift__(self, value) # value << instance
.__ilshift__(self, value) # instance <<= value
.__rshift__(self, value) # instance >> value
.__rrshift__(self, value) # value >> instance
.__irshift__(self, value) # instance >>= value
这些不需要全部定义。例如,要有一个稍微方便一点的语法来向 deque 追加和前置元素,只需实现 .__lshift__()
和 .__rrshift__()
即可。
from collections import deque
class DoubleEndedQueue(deque):
def __lshift__(self, value):
self.append(value)
def __rrshift__(self, value):
self.appendleft(value)
items = DoubleEndedQueue(["middle"])
items << "last"
"first" >> items
items
# DoubleEndedQueue(['first', 'middle', 'last'])
二进制按位运算的优先级全都低于数字运算,但又高于比较运算;一元运算 ~
具有与其他一元算术运算 (+
和 -
) 相同的优先级。
根据操作数的个数,运算符可以分为单目、双目、三目运算符,也称为一元、二元、三元运算符等。若完成一个操作需要两个操作数,则称该运算符为双目运算符;若完成一个操作需要一个操作数,则称该运算符为单目运算符。
在 Python 的按位运算符中,只有反转 ~ 运算符是单目运算,其余都是双目运算。
另外集合和字典也支持类似按位运算的操作。这不是一个广为人知的事实,但位运算符可以执行集合中的运算,例如并集、交集和对称差分,以及合并和更新字典。
总结如下,支持按拉运算的内置数据类型有:
更新时间:2024-05-07 08:46:59 标签:python 整数 位运算