python入门到脱坑经典案例— 6 种数值交换方法
在 Python 中,交换两个变量的值是基础但重要的操作。以下是 6 种数值交换方法,从基础到进阶,适合不同学习阶段:
1. 临时变量法(经典方法)
a, b = 5, 3
temp = a # 暂存a的值
a = b # 将b的值赋给a
b = temp # 将暂存值赋给b
print(a, b) # 输出:3 5
特点:
- 逻辑清晰,适合所有编程语言
- 需要额外临时变量
2. 元组解包法(Python 特有)
a, b = 5, 3
a, b = b, a # 元组解包实现交换
print(a, b) # 输出:3 5
原理:
- 右侧 b, a 先隐式创建元组 (3, 5)
- 左侧按顺序解包赋值
优势: - 简洁高效,无需临时变量
- Python 最常用的交换方式
3. 算术运算法(无临时变量)
方法 1:加减法
a, b = 5, 3
a = a + b # a=8
b = a - b # b=5 (原a值)
a = a - b # a=3 (原b值)
print(a, b) # 输出:3 5
注意:
- 可能发生整数溢出(大数时)
- 仅适用于数值类型
方法 2:乘除法
a, b = 5, 3
a = a * b # a=15
b = a // b # b=5 (原a值)
a = a // b # a=3 (原b值)
print(a, b) # 输出:3 5
限制:
- 不能有 0(除零错误)
- 浮点数可能导致精度丢失
4. 位运算法(高效但难读)
a, b = 5, 3
a = a ^ b # 异或运算
b = a ^ b # 相当于 a ^ b ^ b = a
a = a ^ b # 相当于 a ^ b ^ a = b
print(a, b) # 输出:3 5
特点:
- 无溢出风险
- 仅适用于整数
- 效率最高(底层二进制操作)
5. 列表索引法(非常规技巧)
a, b = 5, 3
lst = [a, b]
a, b = lst[1], lst[0] # 通过列表索引交换
print(a, b) # 输出:3 5
适用场景:
- 需要交换多个值时(如 a,b,c = c,a,b)
6. 字典解包法(扩展思路)
a, b = 5, 3
swap = {'a': b, 'b': a}
a, b = swap['a'], swap['b']
print(a, b) # 输出:3 5
教学意义:
- 展示字典的灵活用法
- 实际开发中不推荐
性能对比
方法 | 速度 | 可读性 | 适用场景 |
元组解包 | 最快 | ★★★★★ | 常规数值交换 |
临时变量 | 快 | ★★★★☆ | 教学/多语言兼容 |
位运算 | 最快 | ★★☆☆☆ | 高性能整数交换 |
算术运算 | 中 | ★★★☆☆ | 无临时变量需求 |
常见问题解答
Q1:元组解包法的底层原理?
Python 先将右侧 b, a 打包成元组,再解包赋值给左侧。等效于:
tmp = (b, a) # 隐式创建元组
a, b = tmp # 解包赋值
Q2:哪些方法会修改原始对象?
所有方法均创建新对象,因为 Python 中整数是不可变类型。但对于可变对象(如列表):
x = [1]; y = [2]
x, y = y, x # 交换的是引用,原列表对象不变
Q3:如何交换列表中的两个元素?
lst = [10, 20, 30]
lst[0], lst[2] = lst[2], lst[0] # 交换第1和第3个元素
print(lst) # 输出 [30, 20, 10]
综合练习
- 交换用户输入的两个数:
a = input("输入a: ")
b = input("输入b: ")
a, b = b, a
print(f"交换后: a={a}, b={b}")
- 实现三个变量的轮换交换:
x, y, z = 1, 2, 3
x, y, z = y, z, x # 1→2→3→1
print(x, y, z) # 输出 2 3 1
- 测试不同方法的执行速度:
import timeit
print(timeit.timeit("a,b = b,a", setup="a=5;b=3")) # 元组解包
print(timeit.timeit("t=a;a=b;b=t", setup="a=5;b=3")) # 临时变量
掌握数值交换后,可进一步学习:
- 列表元素排序(如 lst.sort())
- 多变量同时赋值(如 x, y, z = 1, 2, 3)
- 引用与浅/深拷贝的区别