Python基础指南之运算符优先级对照表与记忆方法详解

 更新时间:2026年06月28日 09:22:56   作者:星河耀银海  
本文详细讲解了Python运算符优先级规则,通过代码示例验证了不同运算符的执行顺序,本文通过大量代码示例帮助读者掌握这一Python编程基础概念,有需要的小伙伴可以了解下

一、开篇

先看一段代码,你能确定它的输出吗?

# 猜猜输出什么?
result = 2 + 3 * 4
print(f"2 + 3 * 4 = {result}")     # 14 还是 20?

result = 10 - 5 - 2
print(f"10 - 5 - 2 = {result}")    # 3 还是 7?

result = 2 ** 3 ** 2
print(f"2 ** 3 ** 2 = {result}")   # 64 还是 512?

result = not True and False or True
print(f"not True and False or True = {result}")   # ?

result = 3 > 2 == True
print(f"3 > 2 == True = {result}")  # ?

result = 10 / 2 * 5
print(f"10 / 2 * 5 = {result}")     # 25.0 还是 1.0?

怎么样,你答对了几题?如果你对其中任何一道题感到不确定,说明你对Python运算符优先级的理解还有模糊地带。

Python中共有50多种运算符,它们到底谁先算、谁后算?什么时候必须加括号、什么时候可以省略?本文将从优先级表、记忆方法、实际案例三个维度,帮你彻底搞懂运算符优先级这个重要但容易被忽视的知识点。

二、Python运算符优先级完整对照表

2.1 从高到低的优先级总表

优先级运算符说明
1(expr...)
[expr...]
{key: value...}
f(arg...)
x[index]
x[index:index]
x.attr
括号/元组显示
列表显示
字典/集合显示
函数调用
索引/下标
切片
属性访问
2**幂运算
3+x-x~x一元正/负/按位取反
4*///%乘/除/整除/取模
5+-加/减
6<<>>左移/右移
7&按位与
8^按位异或
9|按位或
10==!=><>=<=isis notinnot in比较运算符
身份/成员运算符
11not逻辑非
12and逻辑与
13or逻辑或
14if-else条件表达式
15lambdalambda 表达式
16=+=-=*=/= 等赋值运算符
17yieldyield 表达式

2.2 用代码验证优先级

# === 验证乘法高于加法 ===
print(2 + 3 * 4)         # 14 —— 先算3*4=12,再算2+12=14
print((2 + 3) * 4)       # 20 —— 括号改变了优先级
# === 验证一元运算符高于二元运算符 ===
print(-3 ** 2)           # -9 —— 先算3**2=9,再取负= -9
print((-3) ** 2)         # 9 —— 先取负得-3,再平方=9
# === 验证幂运算从右向左 ===
print(2 ** 3 ** 2)       # 512 —— 先算3**2=9,再算2**9=512
print((2 ** 3) ** 2)     # 64 —— 先算2**3=8,再算8**2=64
# === 验证比较运算符优先级高于逻辑运算符 ===
print(3 > 2 == True)     # True —— 等价于 (3 > 2) and (2 == True)
# 3 > 2 是 True, 2 == True 也是 True(True被当作1),所以True
# === 验证乘除优先级相同,从左向右 ===
print(10 / 2 * 5)        # 25.0 —— (10/2)*5 = 5*5 = 25.0
print(10 / (2 * 5))      # 1.0
# === 验证 not > and > or ===
print(not True and False or True)
# = ((not True) and False) or True
# = (False and False) or True
# = False or True
# = True

三、优先级规则的深层理解

3.1 结合性:同优先级的运算符怎么算

大多数运算符具有左结合性(从左向右计算),但有几个例外:

# === 左结合(从左向右)—— 大多数运算符 ===
print(10 - 5 - 2)        # 3 —— (10-5)-2 = 3
print(100 / 10 / 2)      # 5.0 —— (100/10)/2 = 5.0
print(10 + 20 - 5)       # 25 —— (10+20)-5 = 25

# === 右结合(从右向左)—— 特殊运算符 ===

# 1. 幂运算 ** 是右结合
print(2 ** 3 ** 2)       # 512 —— 2 ** (3 ** 2) = 2 ** 9 = 512

# 2. 一元运算符是右结合
print(- - 5)             # 5 —— -(-5) = 5

# 3. 赋值运算符是右结合
a = b = c = 10
# 等价于 a = (b = (c = 10))
# c=10 → b=10 → a=10

# 4. 条件表达式是右结合(但不建议嵌套使用)
x = "正数" if a > 0 else "零或负数"
# 嵌套时要注意可读性

3.2 比较运算符的链式特性

比较运算符有一个特殊之处——它们可以链式使用,但这不是优先级导致的,而是Python语法的特殊设计:

# 链式比较的等价展开
a < b < c
# 等价于 (a < b) and (b < c)
# 注意:不等于 (a < b) < c!

# 验证
print(1 < 3 < 5)     # True —— (1 < 3) and (3 < 5)
print(1 < 3 > 2)     # True —— (1 < 3) and (3 > 2)

# 混合比较和逻辑运算符
print(1 < 3 and 5 > 2)   # True —— 比较优先于and
# 等价于 (1 < 3) and (5 > 2)

3.3 短路求值 vs 优先级

短路求值可能导致某些表达式根本没被执行,但这不影响优先级规则:

# 优先级决定了哪些操作数"绑定"到哪个运算符
# 短路求值决定了表达式的哪些部分实际被执行

def show(v):
    print(f"  计算了 show({v})")
    return v

# 由于and优先级高于or,所以:
# True or False and show(1)
# = True or (False and show(1))
# 短路:True已经确定or的结果,show(1)不会执行
print("True or False and show(1):")
result = True or False and show(1)
print(f"  结果: {result}")

# 但如果改成:
# (True or False) and show(1)
# show(1)会执行,因为and的左边暂时未知
print("(True or False) and show(1):")
result = (True or False) and show(1)
print(f"  结果: {result}")

# 再验证 and 优先级高于 or
print("\n验证优先级: show(0) or show(1) and show(2)")
# 等价于 show(0) or (show(1) and show(2))
# show(0)为假,继续计算show(1) and show(2)
# show(1)为真,需要计算show(2)来确定and的结果
result = show(0) or show(1) and show(2)
print(f"  结果: {result}")

四、高效记忆方法

4.1 分层记忆法

不用死记硬背所有运算符,把它们分成7个层次:

运算符优先级七层记忆法

第一层:访问优先(最高)
    () [] {}  函数调用、下标、属性
    口诀:先拿数据,再做运算

第二层:一元优先
    **  正负号 ~
    口诀:幂和符号紧挨数

第三层:算术优先
    * / // %  (乘除模)
    + -       (加减)
    口诀:先乘除,后加减(小学就学过)

第四层:移位和位运算
    << >>     (移位)
    &         (按位与)
    ^         (按位异或)
    |         (按位或)
    口诀:移位先于位,位与、异或、位或依次排

第五层:比较和成员
    == != > < >= <=    (比较)
    is is not in not in(身份和成员)
    口诀:比较身份与成员,同级一起算

第六层:逻辑运算
    not       (逻辑非)
    and       (逻辑与)
    or        (逻辑或)
    口诀:先非(n)后与(a)再或(o) —— nao!

第七层:赋值最后
    = += -= *= ...
    口诀:算完再存
"""

4.2 口诀记忆

括号函数最优先,
幂和正负跟后边,
乘除整除与取模,
加减移位居中间,
按位与异或位或,
比较成员一条线,
非与或来再赋值,
lambda 最后站一边。

4.3 可视化记忆

优先级金字塔(从下到上,越来越高)

                _________
               /  ()[]{}  \
              /  ** + - ~   \
             /  * / // %     \
            /  + -            \
           /  << >>            \
          /  &                  \
         /  ^                   \
        /  |                    \
       /  == != > < >= <=       \
      /  is in not               \
     /  not                       \
    /  and                         \
   /  or                            \
  /  if-else lambda                  \
 /  = += -= *= /= ...                \
/_____________________________________\

五、必须加括号的场景

5.1 这不是风格问题,是正确性问题

# 场景1:位运算参与逻辑判断
flags = 0b1010
MASK = 0b1000

# ❌ 错误 —— 位运算优先级低于比较!
if flags & MASK == MASK:   # 等价于 flags & (MASK == MASK) = flags & True!
    print("匹配")   # 结果可能不对

# ✅ 正确 —— 括号明确意图
if (flags & MASK) == MASK:
    print("匹配")

# 场景2:左移/右移参与算术运算
# ❌ 模糊
result = 1 << 2 + 3
# 等价于 1 << (2 + 3) = 1 << 5 = 32

# ✅ 明确
result = (1 << 2) + 3    # 4 + 3 = 7

# 场景3:not 作用于复杂表达式
# ❌ 可能误解
if not a > 0 and b > 0:
    pass
# 等价于 (not (a > 0)) and (b > 0)

# ✅ 明确意图
if not (a > 0 and b > 0):    # 两者不都大于0
    pass
if (not a > 0) and b > 0:    # a不大于0 且 b大于0
    pass

# 场景4:复合赋值与表达式混用
# ❌ 不清晰
x = y = f(z) + g(z) * h(z)

# ✅ 拆分开
temp = f(z) + g(z) * h(z)
x = temp
y = temp

5.2 括号的"黄金法则"

  • 当有疑问时,加括号。
  • 当没有疑问时——也考虑加括号。
  • 你的代码读的人比你写的人多,可读性第一。
# 不加括号:需要查优先级表
result = a << b + c * d & e | f

# 加括号:一眼看懂
result = (a << (b + c * d)) & e | f

# 更好:拆分成多步
shift_amount = b + c * d
shifted = a << shift_amount
result = (shifted & e) | f

六、常见优先级错误的真实案例

6.1 案例1:位运算与比较运算符

这是一个真实的bug:

# Bug代码:检查权限位的函数
def has_permission_bug(user_permissions, required):
    """有bug:位运算优先级低于比较"""
    return user_permissions & required == required
    # 等价于: user_permissions & (required == required)
    #       = user_permissions & True
    #       = user_permissions & 1
    # 这几乎总是错的!

# 修复后
def has_permission_fixed(user_permissions, required):
    """修复:加括号"""
    return (user_permissions & required) == required

# 测试
READ = 0b001
WRITE = 0b010
EXECUTE = 0b100

user_perm = READ | WRITE     # 0b011

print(f"Bug版本: {has_permission_bug(user_perm, WRITE)}")   # 可能错误
print(f"修复版本: {has_permission_fixed(user_perm, WRITE)}") # True
print(f"修复版本: {has_permission_fixed(user_perm, EXECUTE)}") # False

6.2 案例2:not 的范围

# 这是另一个常见错误
is_active = True
is_admin = False

# ❌ 本意:"如果不是管理员且是活跃用户"
if not is_admin and is_active:
    print("可以操作")
# 但这等价于 (not is_admin) and is_active
# 效果:is_admin=False, is_active=True → True(碰巧对了)

# 但如果想表达"不是(管理员且活跃)"?
if not (is_admin and is_active):
    print("不是同时为管理员和活跃用户")

# 所以使用not时一定要明确范围

6.3 案例3:海象运算符 :=

# 海象运算符的优先级很低,仅次于逗号
# 几乎总是需要括号!

# ❌ 错误
# if n := len(data) > 0:  # 等价于 if n := (len(data) > 0)
#     pass                 # n是True/False,不是长度!

# ✅ 正确
if (n := len(data)) > 0:
    print(f"数据长度为{n}")

# 另一个例子
# ❌
# result = x := 10 + 5  # SyntaxError

# ✅
result = (x := 10) + 5   # result=15, x=10

七、实战:构建优先级测试器

class PrecedenceTester:
    """运算符优先级互动测试器"""
    
    def __init__(self):
        self.score = 0
        self.total = 0
    
    def test_question(self, expression, expected, explanation=""):
        """测试一道优先级题目"""
        self.total += 1
        try:
            actual = eval(expression)
            if actual == expected:
                self.score += 1
                print(f"✅ 第{self.total}题 正确!{expression} = {actual}")
            else:
                print(f"❌ 第{self.total}题 错误!")
                print(f"   表达式: {expression}")
                print(f"   你的直觉: {expected}")
                print(f"   实际结果: {actual}")
                if explanation:
                    print(f"   💡 解释: {explanation}")
        except Exception as e:
            print(f"⚠️ 第{self.total}题 异常: {e}")
    
    def run_all_tests(self):
        """运行所有测试题"""
        print("=" * 50)
        print("Python 运算符优先级测试")
        print("=" * 50)
        
        # 算术优先级
        self.test_question("2 + 3 * 4", 14, "乘法优先级高于加法")
        self.test_question("10 - 5 - 2", 3, "减法从左向右结合")
        self.test_question("2 ** 3 ** 2", 512, "幂运算从右向左结合")
        self.test_question("-3 ** 2", -9, "幂运算优先级高于一元负号")
        self.test_question("(-3) ** 2", 9, "括号改变优先级")
        self.test_question("10 / 2 * 5", 25.0, "乘除同级,从左向右")
        
        # 位移和位运算
        self.test_question("1 << 2 + 3", 32, "加法优先级高于左移")
        self.test_question("(1 << 2) + 3", 7, "括号改变优先级")
        self.test_question("5 & 3 == 3", 1, "== 优先级高于 &,小心!")
        self.test_question("(5 & 3) == 3", False, "括号改变优先级")
        
        # 逻辑优先级
        self.test_question("not True and False", False, 
                          "not > and: (not True) and False")
        self.test_question("not (True and False)", True, "括号改变优先级")
        self.test_question("True or False and False", True,
                          "and > or: True or (False and False)")
        self.test_question("(True or False) and False", False, "括号改变优先级")
        
        # 比较和逻辑
        self.test_question("3 > 2 and 4 < 5", True, "比较 > and")
        self.test_question("3 > 2 == True", True, "链式比较")
        
        # 综合
        self.test_question("2 + 3 * 4 ** 2 - 8 / 2", 
                          46.0, "综合优先级测试")
        
        print(f"\n{'='*50}")
        print(f"总计: {self.total}题, 正确: {self.score}题")
        print(f"得分: {self.score/self.total*100:.0f}%")

# 运行测试
tester = PrecedenceTester()
tester.run_all_tests()

八、开发工具中的优先级检查

8.1 利用IDE的警告

# 现代IDE(PyCharm、VS Code + Pylance)会给出优先级警告
# 例如:
flags = 0b1010
MASK = 0b1000

# 当你写:
result = flags & MASK == MASK
# IDE通常会显示警告:"Equality check is not the same as bitwise and"
# 建议改为:
result = (flags & MASK) == MASK

8.2 使用AST查看Python如何解析

import ast

def show_precedence(expr_str):
    """使用AST查看Python如何解析表达式"""
    print(f"\n表达式: {expr_str}")
    try:
        tree = ast.parse(expr_str, mode='eval')
        print(f"AST结构: {ast.dump(tree, indent=2)}")
    except SyntaxError as e:
        print(f"语法错误: {e}")

# 演示不同表达式如何被解析
show_precedence("2 + 3 * 4")
show_precedence("not True and False")
show_precedence("1 << 2 + 3")
show_precedence("flags & MASK == MASK")

九、本章小结

本文我们系统学习了Python运算符优先级的所有重要知识:

  • 完整的优先级表:从括号(最高)到赋值(最低),一共17个层级。记住:括号 > 幂 > 一元 > 乘除 > 加减 > 移位 > 位运算 > 比较 > not > and > or > 赋值。
  • 结合性:大多数运算符左结合(从左向右),但幂运算**、一元运算符和赋值运算符是右结合(从右向左)。
  • 记忆方法:七层分层记忆法 + 口诀记忆 + 优先级金字塔,让记忆不再困难。
  • 必须加括号的场景:位运算+比较、not+复杂表达式、海象运算符——这些场景加括号是正确性的要求,不是风格问题。
  • 常见错误flags & MASK == MASK(位运算被比较运算符截胡)、not a and b(not的范围误解)——这些都是真实代码中的bug来源。
  • 工具辅助:IDE的警告、AST模块——利用工具检查优先级问题。

运算符优先级不需要死记硬背。当你对某个表达式的求值顺序不确定时,加括号总是最安全的选择。代码是写给人看的,清晰比简洁更重要。⌨️ 下一篇文章,我们将进入Python流程控制的世界——从if条件判断开始!

以上就是Python基础指南之运算符优先级对照表与记忆方法详解的详细内容,更多关于Python运算符优先级的资料请关注脚本之家其它相关文章!

相关文章

  • Python CleverCSV轻松处理CSV文件指南

    Python CleverCSV轻松处理CSV文件指南

    这篇文章主要为大家介绍了Python CleverCSV轻松处理CSV文件全面指南,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • 关于Python中flask-httpauth库用法详解

    关于Python中flask-httpauth库用法详解

    这篇文章主要介绍了关于Python中flask-httpauth库用法详解,Flask-HTTPAuth是一个 Flask 扩展,它简化了 HTTP 身份验证与 Flask 路由的使用,需要的朋友可以参考下
    2023-04-04
  • 深入了解Python中的变量

    深入了解Python中的变量

    这篇文章主要为大家介绍了Python的变量,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • 一个计算身份证号码校验位的Python小程序

    一个计算身份证号码校验位的Python小程序

    闲着无事,便想写个实用点的Python小程序,如何计算机身份证号码的校验位,这样的文章在网上一抓一大把,这里仅简单介绍下吧
    2014-08-08
  • python 函数定义与使用实践案例

    python 函数定义与使用实践案例

    本篇教程详细介绍了Python函数的定义与使用,包括函数参数、返回值、变量作用域、匿名函数、高阶函数、递归函数等重要概念,感兴趣的朋友跟随小编一起看看吧
    2025-10-10
  • Python基于sklearn库的分类算法简单应用示例

    Python基于sklearn库的分类算法简单应用示例

    这篇文章主要介绍了Python基于sklearn库的分类算法,结合简单实例形式分析了Python使用sklearn库封装朴素贝叶斯、K近邻、逻辑回归、SVM向量机等常见机器学习算法的分类调用相关操作技巧,需要的朋友可以参考下
    2018-07-07
  • Python中常用的数据结构与算法优化技巧指南

    Python中常用的数据结构与算法优化技巧指南

    Python是一种强大而灵活的编程语言,它提供了丰富的数据结构和算法库,但是在处理大规模数据或者需要高效运行的情况下,需要考虑一些优化技巧,本文将介绍一些Python中常用的数据结构与算法优化技巧,需要的朋友可以参考下
    2024-05-05
  • Python如何用wx模块创建文本编辑器

    Python如何用wx模块创建文本编辑器

    在本篇文章里小编给大家整理的是关于Python的wx模块创建文本编辑器方法,需要的朋友们可以参考下。
    2020-06-06
  • Python XML 解析方法

    Python XML 解析方法

    Python作为一种广泛使用的编程语言,提供了多种库用于解析XML文件,本文将详细介绍Python中XML解析的常用方法,包括xml.etree.ElementTree和lxml库,以及它们的使用场景和注意事项,感兴趣的朋友跟随小编一起看看吧
    2025-12-12
  • 详解Windows下源码编译PaddlePaddle

    详解Windows下源码编译PaddlePaddle

    这篇文章主要为大家介绍了Windows下从源码编译PaddlePaddle解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04

最新评论