AIGC标识 Python 逻辑运算符与位运算符详解

一文搞懂 Python 中 and / or / not 与 & | ^ ~ << >> 的区别、陷阱与实战用法。

前言

Python 中有两类容易混淆的运算符:逻辑运算符(and、or、not)和位运算符(&、|、^、~、<<、>>)。它们外观相似、在某些场景下"看起来"结果一样,但设计目的和工作机制完全不同。本文系统梳理两者的用法、区别与常见陷阱。

一、逻辑运算符(3 个)

运算符 含义 示例
and 与 True and False → False
or 或 True or False → True
not 非 not True → False

1.1 短路求值

and 左边为假就不再计算右边;or 左边为真就不再计算右边:

False and print("不会执行")   # 无输出
True  or  print("不会执行")   # 无输出

常用于安全判断(先判空再取值):

if obj is not None and obj.value > 10:   # obj 为 None 时不会崩溃

1.2 返回值不是布尔,而是操作数之一

这是 Python 逻辑运算符最容易踩坑的地方:

3 and 5     # 5     ← and 返回第一个假值;都真则返回最后一个
0 or "x"    # 'x'   ← or 返回第一个真值;都假则返回最后一个
not 3       # False ← 只有 not 恒返回布尔

利用 or 给默认值是一个常见惯用法:

name = input_name or "匿名"

1.3 真值判断规则

非布尔值参与逻辑运算时,以下值为假,其余为真:

  • 数字 0、0.0
  • 空序列/集合:''、[]、{}、set()、()
  • None

二、位运算符(6 个)

位运算符对整数的二进制位逐位操作。设 x = 0b1100(十进制 12)、y = 0b1010(十进制 10):

运算符 含义 示例
& 按位与 12 & 10 → 8(0b1000)
| 按位或 12 | 10 → 14(0b1110)
^ 按位异或 12 ^ 10 → 6(0b0110)
~ 按位取反 ~12 → -13
<< 左移 12 << 1 → 24(相当于 ×2)
>> 右移 12 >> 1 → 6(相当于 ÷2)

以 12 & 10 为例逐位推演:

  1100  (12)
& 1010  (10)
------
  1000  (8)   ← 两位都为 1 才得 1

2.1 ~n 为什么等于 -n - 1

Python 整数按补码语义理解:取反后所有位翻转,等价于 -n - 1。例如 ~5 = -6,~12 = -13。

2.2 常见用途

n & 1          # 判断奇偶:结果 1 为奇,0 为偶
n & (n - 1)    # 清除最低位的 1;结果为 0 说明 n 是 2 的幂
n ^ n          # 0(任何数异或自己为 0)—— 找"只出现一次的数字"等算法题常用
n << k, n >> k # 乘 / 除 2 的幂
flags | 0b100  # 置位;flags & 0b100 测位 —— 状态标志位(位掩码)

三、两者对比

逻辑运算符 and / or / not 位运算符 & | ^ ~ << >>
操作对象 整体真值 二进制的每一位
短路求值 有 无(两边都会计算)
返回值 操作数之一(not 除外) 整数
适用类型 任意对象 仅整数(及自定义了 __and__ 等方法的类型)

四、易混淆点与陷阱

4.1 & / | 用在布尔值上

True & False 与 True and False 结果一样,但机制不同——位运算不短路,两边永远求值:

True & False   # False,结果一样,但两边都会计算

4.2 条件判断中误用位运算符

# 想短路,却用了位运算符——右边永远执行,且优先级混乱
obj is not None & obj.value > 10   # ❌ 错误用法

条件判断请老老实实用 and:

obj is not None and obj.value > 10  # ✅

4.3 pandas / NumPy 中的例外

对 DataFrame、ndarray 等向量对象做元素级布尔运算时,必须用 &、|、~(它们重载了位运算符),且要加括号:

df[(df.a > 1) & (df.b < 5)]        # ✅ 位运算符 + 括号
df[df.a > 1 and df.b < 5]          # ❌ 报错:真值有歧义

五、总结

  • and / or / not 操作的是"整个值的真假":支持短路求值,返回操作数之一。
  • & | ^ ~ << >> 操作的是"二进制的每一位":不短路,返回整数。
  • 日常条件判断用逻辑运算符;奇偶判断、位掩码、状态位、算法题用位运算符。
  • 向量库(pandas/NumPy)筛选数据时,用位运算符且记得加括号。

一句话总结:逻辑运算符判断"值是真还是假",位运算符操作"二进制每一位"——前者面向流程控制,后者面向底层计算。

posted on 2026-11-03 10:45  斜月三星一太阳  阅读(3)  评论(0)    收藏  举报