Python运算

Python运算符:数据魔法的核心语法

承接上篇《Python变量与类型:编程的基石》,当你的变量已就位,数据类型清晰,运算符就是让数据”活”起来的魔法咒语。本文带你掌握Python中操控数据的12类核心运算符,避开90%新手常见的逻辑陷阱。


一、运算符全景图:数据的指挥家

Python中的运算符是操作变量和值的特殊符号,它们让数据流动、比较、组合。关键认知

🧠 运算符不是数学公式,而是对特定类型对象的操作协议
即使符号相同(如+),在字符串和数字上会触发完全不同的类方法__add__ vs __concat__

类别 运算符示例 操作对象 本质
算术运算符 + - * / // % ** 数字、序列 数学计算
比较运算符 == != > < >= <= 可比较对象 返回布尔值
逻辑运算符 and or not 布尔上下文 逻辑判断
赋值运算符 = += -= *= /= %= 所有变量 更新引用
成员运算符 in not in 序列、集合、字典 检查归属
身份运算符 is is not 任意对象 检查内存地址

二、算术运算:不只是加减乘除

# 整数 vs 浮点数陷阱
print(5 / 2)    # 2.5 (浮点除)
print(5 // 2)   # 2 (向下取整除) → 不是四舍五入!
print(-5 // 2)  # -3 (向负无穷取整)

# 幂运算的惊喜
print(2**3**2)  # 512 (2**(3**2)=2^9),不是(2^3)^2!

# 序列的魔法操作
print("ha" * 3)      # "hahaha" (字符串重复)
print([0] * 3)       # [0, 0, 0] (列表浅拷贝 → 改动陷阱!)
print([ [0] ] * 3)   # [[0], [0], [0]] → 全部指向同一对象!

⚠️ 致命陷阱

a = [0] * 3
a[0] = 1
print(a)  # [1, 0, 0] → 预期结果 ✅

b = [[0]] * 3
b[0][0] = 1
print(b)  # [[1], [1], [1]] → 全部被修改!❌
# 解决:b = [[0] for _ in range(3)]

三、比较与逻辑:超越真与假

比较运算的潜规则

# 浮点精度灾难
print(0.1 + 0.2 == 0.3)  # False! (实际=0.30000000000000004)

# 链式比较的优雅
age = 25
print(18 <= age < 65)    # True (等价于 18<=age and age<65)

# 字符串比较是字典序
print("apple" < "banana") # True
print("Z" < "a")          # True (ASCII: 'Z'=90 < 'a'=97)

逻辑运算的”假值”本质

🔍 Python中 and/or 返回的是操作数本身,而非布尔值!

# "假值"集合:False, 0, 0.0, "", [], (), {}, None
print("Hello" and "")   # "" (短路返回第二个操作数)
print([] or "default")  # "default" (短路返回真值)

# 实战:安全获取字典键
user = {"name": "Alice"}
print(user.get("age") or 18)  # 18 (当键不存在时返回默认值)

四、赋值与特殊运算符:效率与陷阱并存

赋值运算的连招

# 增量赋值的陷阱
nums = [1, 2]
nums += [3]  # 等价于 nums.extend([3])
print(nums)  # [1, 2, 3] → 原地修改!

# 但不可变对象会新建引用
s = "hello"
s += " world"  # 创建新字符串(上一篇知识点)

身份 vs 等值:新手死亡区

a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)  # True (值相等)
print(a is b)  # False (不同对象)

c = b
print(b is c)  # True (同一引用)

# 字符串/数字小对象池
m = 256
n = 256
print(m is n)  # True (小整数驻留)

x = 257
y = 257
print(x is y)  # False (大整数不驻留) → 依赖解释器!

💡 黄金法则

  • 值比较用 ==
  • 内存地址检查才用 is(如 x is None

五、运算符优先级:构建复杂逻辑的脚手架

当算式如 3 + 4 * 2 > 10 and "a" in "abc" 出现时,优先级规则决定执行顺序:

优先级 运算符 结合性
最高 ** 右结合
  * / // % 左结合
  + - 左结合
  == != > < 左结合
  not 右结合
  and 左结合
最低 or 左结合

秘技:用括号明确意图!
year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
(判断闰年 - 比无括号版本清晰10倍)


实战练习:检验你的运算直觉

# 1. 修复浮点比较(按0.01精度)
if 0.3 == 0.1 + 0.2: print("Equal") 

# 2. 预测结果
x = 5
y = x > 3 and "A" or "B"
print(y)

# 3. 身份谜题
a = 257
b = 257
print(a is b)  # 结果取决于运行环境!

答案:

  1. abs(0.1 + 0.2 - 0.3) < 1e-6
  2. "A"(短路逻辑:5>3为真 → 返回"A"
  3. 可能True也可能False!(CPython在交互式环境缓存小整数,但脚本中可能不缓存)

为什么这比数学公式更强大?

  1. 多态性+ 既可加数字也可拼字符串 → 面向对象的优雅
  2. 短路求值exists and exists.load_data() → 避免None错误
  3. 惯用写法value = input() or "default" → 简化空值处理

💎 核心总结
“值相等看==,内存相同验is
逻辑短路取原值,浮点比较用区间”

掌握这些运算规则,你将摆脱”为什么这里不工作”的困扰,写出精准、高效、Pythonic的代码。