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) # 结果取决于运行环境!
答案:
abs(0.1 + 0.2 - 0.3) < 1e-6"A"(短路逻辑:5>3为真 → 返回"A")- 可能True也可能False!(CPython在交互式环境缓存小整数,但脚本中可能不缓存)
为什么这比数学公式更强大?
- 多态性:
+既可加数字也可拼字符串 → 面向对象的优雅 - 短路求值:
exists and exists.load_data()→ 避免None错误 - 惯用写法:
value = input() or "default"→ 简化空值处理
💎 核心总结:
“值相等看==,内存相同验is
逻辑短路取原值,浮点比较用区间”
掌握这些运算规则,你将摆脱”为什么这里不工作”的困扰,写出精准、高效、Pythonic的代码。