【Python编程日志】Python运算符进阶:位 | 成员 | 身份运算符

🌈个人主页:聆风吟_

🔥系列专栏:Python编程日志C标准库

🔖少年有梦不应止于心动,更要付诸行动。


文章目录

📋前言

上一篇文章我们讲解了算术、赋值、比较、逻辑四类基础运算符,覆盖日常开发最常用的数值计算与条件判断场景。本篇继续补齐 Python 剩余三类进阶运算符:位运算符、成员运算符、身份运算符。


一、位运算符

1.1 定义

位运算的操作对象是整数类型,它会将数字转换为二进制形式,然后对每一位(0 或 1)进行逐位计算,最后返回一个新的整数值。

运算符 名称 运算逻辑
& 按位与 同位均为1,结果位为1,否则为0
` ` 按位或
^ 按位异或 同位数字不同则为1,相同则为0
~ 按位取反 所有比特位0、1互换(单目运算符)
<< 左移 二进制整体左移,右侧低位补0
>> 右移 二进制整体右移,左侧补充符号位

前置知识:Python 整数底层以 补码 形式存储,以下示例默认使用 8 位二进制方便理解和演示。

先定义两个变量,统一演示:

python 复制代码
a = 6   # 二进制 0000 0110
b = 3   # 二进制 0000 0011
1)按位与 &
复制代码
  0000 0110
& 0000 0011
------------
  0000 0010  → 十进制 2
python 复制代码
print(a & b)  # 2

实用技巧:n & 1 判断数字奇偶,结果为1是奇数,0是偶数。

2)按位或 |
复制代码
  0000 0110
| 0000 0011
------------
  0000 0111  → 十进制 7
python 复制代码
print(a | b)  # 7
3)按位异或 ^
复制代码
  0000 0110
^ 0000 0011
------------
  0000 0101  → 十进制 5
python 复制代码
print(a ^ b)  # 5

核心特性:

  • x ^ x = 0
  • x ^ 0 = x

常用场景:不借助临时变量交换两个数字、简单数据加密。

4)按位取反 ~

计算公式:~x = -x - 1

示例:~6 = -6 - 1 = -7

复制代码
~ 0000 0110
------------
  1111 1001  → 十进制 -7
python 复制代码
print(~a) # -7
5)左移 <<

二进制整体左移n位,左侧溢出位舍弃,右侧补0;数学等价:数值 × 2ⁿ

复制代码
   0000 0110
<<         1
------------
   0000 1100  → 12
python 复制代码
print(a << 1)  # 12
6)右移 >>

算术右移规则:二进制整体右移n位,右侧溢出舍弃;正数高位补0,负数高位补1(保证符号不变);数学等价:数值 ÷ 2ⁿ(向下取整)

复制代码
   1111 1010
>>         1
------------
   1111 1101  → -3
python 复制代码
print(a >> 1)   # 3
print(-a >> 1)  # -3

1.2 位运算实用小技巧

  1. n & 1 快速判断数字奇偶;
  2. 移位 <</>> 替代 *2//2,底层运算速度更快;
  3. 异或交换两数,无需中间变量:
python 复制代码
x, y = 3, 6
x = x ^ y
y = x ^ y
x = x ^ y
print(x, y)  # 6 3

二、成员运算符

2.1 定义

成员运算符用于检测元素是否存在于字符串、列表、元组、集合、字典等容器序列中,返回布尔值 True/False

运算符 作用
in 元素存在于容器,返回True;不存在返回False
not in 元素不存在于容器,返回True;存在返回False

2.2 各类容器代码示例

(1)列表、元组
python 复制代码
# 列表
lst = [10, 20, 30]
print(20 in lst)       # True
print(40 in lst)       # False
print(40 not in lst)   # True

# 元组
tup = (1, 2, 3)
print(1 in tup)        # True
(2)字符串(匹配子串,区分大小写)
python 复制代码
s = "hello python"
print("python" in s)   # True
print("java" in s)     # False
print("h" not in s)    # False
print("A" in "abc")    # False 大小写严格匹配
(3)集合
python 复制代码
se = {5, 6, 7}
print(6 in se)         # True
(4)字典:仅检测键,不检测值

如需判断值是否存在,调用 .values()

python 复制代码
dic = {"name": "Tom", "age": 18}
print("name" in dic)          # True,匹配字典键
print(18 in dic)              # False,不会匹配value
print(18 in dic.values())     # True,检测字典值

2.3 拓展使用说明

  1. 常规场景:搭配if条件判断
python 复制代码
nums = [1,2,3,4]
n = 3
if n in nums:
    print("存在该元素")
else:
    print("不存在该元素")
  1. 嵌套容器仅匹配顶层元素
python 复制代码
a = [[1,2], 3]
print(1 in a)    # False,1是子列表内部元素
print([1,2] in a)# True,[1,2]是顶层元素
  1. 优先级:成员运算符优先级低于比较运算符,高于逻辑运算符。

三、身份运算符

3.1 定义

身份运算符对比两个变量的内存地址 ,判断二者是否指向同一个内存对象,和单纯对比数值的 == 有本质区别。

运算符 作用
is 两个变量内存地址完全一致(同一对象),返回True
is not 两个变量内存地址不同(独立对象),返回True

3.2 核心区分:is 和 ==

  • ==:仅对比两个变量存储的值是否相等;
  • is:对比两个变量的内存地址,判断是否为同一个对象。

示例1:数值相等,但属于两个独立对象

python 复制代码
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)   # True,列表内容完全一致
print(a is b)   # False,两块独立内存,地址不同

示例2:变量引用同一内存对象

python 复制代码
c = a          # c直接引用a的内存地址
print(c is a)  # True
print(c == a)  # True

3.3 id() 内置函数查看内存地址

id(变量) 会返回对象唯一内存编号,直观验证 is 判断逻辑:

python 复制代码
a = [1,2]
b = [1,2]
print(f"a 的地址: {id(a)}")
print(f"b 的地址: {id(b)}")
print(a is b)  # 地址不同 → False

c = a
print(f"c 的地址: {id(c)}")
print(c is a)  # 地址相同 → True

3.4 常用场景:判断None必须用is

开发规范中,判断变量是否为空值 None,统一使用 is / is not,不使用 ==

python 复制代码
num = None
if num is None:
    print("变量为空")

if num is not None:
    print("变量不为空")

四、运算符优先级总表

数字越小代表优先级越高,同级运算符遵循对应结合性;逻辑混乱时直接添加括号 () 强制划分计算顺序。

优先级序号 运算符分类 运算符 结合性
1(最高) 括号 ()
2 幂运算 ** 右结合
3 单目运算符 +x -x ~x 右结合
4 乘除算术 * / // % 左结合
5 加减算术 + - 左结合
6 移位运算 << >> 左结合
7 按位与 & 左结合
8 按位异或 ^ 左结合
9 按位或 ` `
10 比较/身份/成员 > >= < <= == != is is not in not in 左结合
11 逻辑非 not 右结合
12 逻辑与 and 左结合
13 逻辑或 or 左结合
14(最低) 赋值运算符 = += -= *= /= //= %= **= 右结合

补充说明:

  1. 结合性释义:
    • 左结合:同级运算符从左至右依次计算;
    • 右结合:同级运算符从右至左依次计算;
  2. 开发建议:复杂多层表达式不要依赖优先级记忆,使用括号拆分,代码可读性更强、减少逻辑bug。

全文总结

本文完整讲解Python三类进阶运算符:

  1. 位运算符:基于二进制补码逐位运算,提供奇偶判断、快速乘除、异或交换变量等高效开发技巧;
  2. 成员运算符in/not in可检测容器内元素,字典仅默认检索键,嵌套容器仅匹配顶层对象;
  3. 身份运算符is对比内存地址,和仅对比数值的==本质不同,判空None规范使用is None

今天的干货分享到这里就结束啦!如果觉得文章还可以的话,希望能给个三连支持一下,聆风吟的主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的最大动力!