上一期我们掌握了身份运算符,学会了精准判断变量指向的对象是否同一;今天继续深耕Python运算符系列——位运算符。它是Python中偏向底层的运算符,直接操作二进制位进行运算,虽不像算术、比较运算符那样常用,却在性能优化、底层开发、数据加密等场景中不可或缺,掌握它,能让你从底层理解数据运算逻辑,写出更高效、更简洁的代码。
很多人觉得位运算符“晦涩难懂”,其实核心逻辑很简单——计算机底层所有数据都以二进制(0和1)形式存储,位运算符就是直接对这些二进制位进行操作(如移位、与、或、非),运算速度远超普通算术运算,尤其适合处理大量数据或对性能有要求的场景。
📌 什么是位运算符?
位运算符,本质是直接对整数的二进制位进行操作的运算符,运算对象必须是整数(Python会自动将整数转换为二进制,再执行位运算,最终返回十进制结果)。
简单来说,位运算符就像“操作二进制的积木”:把整数拆成0和1组成的二进制序列,对每一位进行对应操作,再将操作后的二进制序列转换回十进制,就是位运算的结果。
核心说明:Python中的位运算符共有6种,可分为“逻辑位运算”和“移位运算”两类,用法固定,只要掌握二进制基础,就能快速上手,重点是理解每一种运算的二进制操作逻辑。
# 先了解:整数与二进制的转换(辅助理解位运算)# bin()函数:将整数转为二进制字符串(前缀0b表示二进制)print(bin(5)) # 输出0b101,5的二进制是101print(bin(3)) # 输出0b11,3的二进制是11print(int(0b101))# 输出5,二进制转十进制
🔧 6种位运算符
Python中的位运算符分为两类,逻辑位运算(4种)和移位运算(2种),每一种都有明确的二进制操作规则,结合示例理解,无需死记硬背。
一、逻辑位运算(4种,对二进制位逐位操作)
逻辑位运算的核心是“逐位判断”,将两个整数的二进制位对齐,对每一位执行相同的逻辑操作,规则与布尔值逻辑运算相似,但操作对象是二进制位(0和1)。
1. & 按位与:两个位都为1,结果才为1
语法:整数1 & 整数2,将两个整数的二进制位逐位对比,只有当对应位都为1时,结果位才为1;否则为0。
# 示例:5 & 3# 5的二进制:0b101# 3的二进制:0b011(对齐后:0b011)# 逐位对比:1&0=0,0&1=0,1&1=1 → 结果二进制0b001(十进制1)print(5 & 3) # 输出1# 应用场景:判断整数是否为奇数(最常用)# 奇数二进制末位是1,偶数末位是0,与1按位与,结果为1则是奇数print(7 & 1) # 输出1(7是奇数)print(8 & 1) # 输出0(8是偶数)
2. | 按位或:两个位有一个为1,结果就为1
语法:整数1 | 整数2,逐位对比两个整数的二进制位,只要对应位有一个为1,结果位就为1;两个都为0时,结果位才为0。
# 示例:5 | 3# 5的二进制:0b101# 3的二进制:0b011# 逐位对比:1|0=1,0|1=1,1|1=1 → 结果二进制0b111(十进制7)print(5 | 3) # 输出7# 应用场景:将某几位二进制置为1(底层开发常用)num = 5 # 0b101# 将第2位(从0开始计数)置为1,用 0b010(2)按位或print(num | 2) # 输出7(0b111)
3. ^ 按位异或:两个位不同,结果才为1
语法:整数1 ^ 整数2,逐位对比两个整数的二进制位,对应位不同(一个0、一个1),结果位为1;对应位相同(都0或都1),结果位为0。
# 示例:5 ^ 3# 5的二进制:0b101# 3的二进制:0b011# 逐位对比:1^0=1,0^1=1,1^1=0 → 结果二进制0b110(十进制6)print(5 ^ 3) # 输出6# 应用场景1:两个相同数异或,结果为0print(10 ^ 10) # 输出0# 应用场景2:交换两个变量的值(无需临时变量)a = 10b = 20a = a ^ bb = a ^ ba = a ^ bprint(a, b) # 输出20 10(成功交换)
4. ~ 按位非:对二进制位取反,0变1,1变0
语法:~ 整数,对整数的每一位二进制位取反(0→1,1→0),同时遵循Python的补码规则,结果为“-(原数+1)”(无需深入补码,记住公式即可快速计算)。
# 示例:~5# 5的二进制:0b101,取反后为0b...11111010(补码)# 简化计算:~x = -(x + 1)print(~5) # 输出-6(-(5+1) = -6)print(~3) # 输出-4(-(3+1) = -4)print(~0) # 输出-1(-(0+1) = -1)
二、移位运算(2种,对二进制位进行左右移动)
移位运算的核心是“将二进制位整体左移或右移”,移动后空缺的位用0填充(右移时负数特殊处理,无需关注,重点掌握正数移位),运算效率极高,常用于快速计算倍数(左移乘2,右移除2)。
1. << 左移:将二进制位整体左移n位,空缺位补0
语法:整数 << n,将整数的二进制位向左移动n位,左边移出的位丢弃,右边空缺的位补0,等价于“整数 × 2ⁿ”(快速计算2的倍数)。
# 示例1:5 << 1(左移1位,等价于5×2¹)# 5的二进制:0b101 → 左移1位:0b1010(十进制10)print(5 << 1) # 输出10# 示例2:5 << 2(左移2位,等价于5×2²)# 5的二进制:0b101 → 左移2位:0b10100(十进制20)print(5 << 2) # 输出20# 应用场景:快速计算2的倍数,比乘法运算更高效print(8 << 3) # 8×8=64,输出64
2. >> 右移:将二进制位整体右移n位,空缺位补0
语法:整数 >> n,将整数的二进制位向右移动n位,右边移出的位丢弃,左边空缺的位补0(正数),等价于“整数 ÷ 2ⁿ”(快速计算除以2的倍数,向下取整)。
# 示例1:10 >> 1(右移1位,等价于10÷2¹=5)# 10的二进制:0b1010 → 右移1位:0b101(十进制5)print(10 >> 1) # 输出5# 示例2:20 >> 2(右移2位,等价于20÷2²=5)# 20的二进制:0b10100 → 右移2位:0b101(十进制5)print(20 >> 2) # 输出5# 应用场景:快速除以2的倍数,向下取整print(7 >> 1) # 7÷2=3.5,向下取整为3,输出3
✅ 位运算符的核心特性
运算对象必须是整数:位运算符仅能操作整数,若传入浮点数,会报错(需先用int()转换为整数)。
运算速度极快:直接操作底层二进制位,无需经过十进制与二进制的转换(Python自动处理),运算速度比值运算、逻辑运算更快。
结果为整数:无论何种位运算,最终结果都会以十进制整数返回,方便后续使用。
遵循补码规则:对于负数,位运算会基于补码进行(无需深入理解补码细节,记住常用运算的结果规律即可)。
🌟 实战常用场景
位运算符虽偏向底层,但在实际编程中仍有不少实用场景,以下4个场景最常用,掌握后可直接应用,提升代码效率。
场景1:判断整数奇偶性
利用“按位与&1”,比取余运算(%2)更高效,逻辑更简洁,是判断奇偶性的最优方式之一。
# 判断奇偶性def is_odd(num): return num & 1 == 1 # 结果为1则是奇数,0则是偶数print(is_odd(7)) # 输出True(奇数)print(is_odd(10)) # 输出False(偶数)
场景2:交换两个变量的值
利用“按位异或^”,可实现无临时变量交换两个整数的值,代码简洁,无需额外占用内存。
# 无临时变量交换两个变量a = 100b = 200# 交换逻辑(3行代码)a = a ^ bb = a ^ ba = a ^ bprint(a, b) # 输出200 100(交换成功)
场景3:快速计算2的倍数
左移<<和右移>>,分别对应“乘2ⁿ”和“除2ⁿ”,运算速度比普通乘法、除法更快,适合高频计算场景。
# 快速计算倍数print(6 << 3) # 6×8=48(左移3位,2³=8)print(64 >> 2) # 64÷4=16(右移2位,2²=4)print(9 >> 1) # 9÷2=4(向下取整)
场景4:数据加密/解密
利用按位异或^的特性(一个数异或同一个数两次,结果不变),可实现简单的数据加密和解密,适合简单场景下的信息保护。
# 简单数据加密和解密key = 123 # 加密密钥(自定义)data = 456 # 待加密数据# 加密:数据与密钥异或encrypted = data ^ keyprint("加密后:", encrypted) # 输出加密后的结果(随机整数)# 解密:加密结果与密钥再次异或decrypted = encrypted ^ keyprint("解密后:", decrypted) # 输出456(还原原始数据)
❌ 必避的4个位运算坑
位运算符的逻辑的基于二进制,容易因忽视二进制规则、混淆运算场景而踩坑,这4个坑一定要避开,确保代码逻辑正确。
坑1:用位运算符操作浮点数:位运算符仅支持整数,传入浮点数会直接报错,需先用int()转换为整数(如3.5 & 1会报错)。
坑2:混淆左移/右移与乘法/除法:左移<<n 等价于“乘2ⁿ”,但仅适用于整数;右移>>n 等价于“除2ⁿ”,且是向下取整(如7>>1=3,而非3.5)。
坑3:忽视按位非的结果规律:按位非~x的结果是“-(x+1)”,而非简单的“反数”(如~5=-6,而非-5),避免计算错误。
坑4:用位运算符替代比较运算:位运算符是操作二进制位,不能替代比较运算符(如a & b == 1是判断奇偶,而非比较大小)。
# 避坑示例(必看)# 坑1:操作浮点数(报错)# print(3.5 & 1) # 报错:unsupported operand type(s) for &: 'float' and 'int'# 坑2:右移向下取整(易错)print(7 >> 1) # 输出3,不是3.5print(-7 >> 1) # 输出-4(负数右移遵循补码,无需深入,记住结果规律即可)# 坑3:按位非计算错误print(~5) # 输出-6,不是-5print(~-6) # 输出5(验证:~x = -(x+1))# 坑4:混淆位运算与比较运算a = 5b = 3print(a & b == 1) # 输出True(判断奇偶,不是比较a&b和1的大小)
📝 核心总结
位运算符核心:直接操作整数的二进制位,共6种,分为逻辑位运算(&、|、^、~)和移位运算(<<、>>);
核心用法:记住每种运算的二进制规则,无需死记硬背,结合示例理解,重点掌握常用场景;
实战重点:判断奇偶、交换变量、快速计算倍数、简单加密,这4个场景可直接套用;
避坑关键:仅操作整数、记住左移右移的计算规律、掌握按位非的结果公式,避开4个常见坑。
位运算符虽然偏向底层,但并不难掌握,它能帮你更深入理解计算机的数据存储和运算逻辑。看似小众的知识点,往往能在关键场景中发挥巨大作用,让你的代码更高效、更简洁。
每一个底层知识点的积累,都是提升编程能力的基石,深耕每一个细节,才能真正实现从“会编程”到“编好程”的跨越。