python中的一些运算符
python中的一些运算符看着简单,但里面门道不少,尤其对于刚接触 Python 或者从其他语言转过来的朋友来说,很容易混淆。我们一起来掰扯清楚。
我们分两组来看:** 和 * 是一组,// 和 / 是另一组。
第一组:**
(幂运算) vs *
(乘法)
这个区别最直接,一个是乘方,一个是乘法。
*
(乘法运算符)
这个就是我们从小用到大的乘法。在 Python 里,它不仅能算数字相乘,还有一些很 Pythonic 的妙用。
1. 数字乘法
result = 5 * 3
print(result) # 输出: 15
result = 3.14 * 2
print(result) # 输出: 6.28
2. 序列重复(Python特色)
这是 *
在 Python 里的一个神技,可以用来快速重复列表、字符串等序列类型。
# 重复列表
zeros = [0] * 5
print(zeros) # 输出: [0, 0, 0, 0, 0]
# 重复字符串
greeting = "Ha" * 3
print(greeting) # 输出: "HaHaHa"
# 重复元组
point = (1, 2) * 2
print(point) # 输出: (1, 2, 1, 2)
**
(幂运算符)
这个就是数学里的“多少次方”。它比很多语言(比如用 Math.pow()
或者 ^
)要简洁得多。
1. 整数次幂
# 2的3次方
result = 2 ** 3
print(result) # 输出: 8
# 5的平方
result = 5 ** 2
print(result) # 输出: 25
2. 分数次幂(开方)
这个用法非常实用,可以用来计算平方根、立方根等。
# 计算16的平方根 (16的1/2次方)
result = 16 ** 0.5
print(result) # 输出: 4.0
# 计算27的立方根 (27的1/3次方)
result = 27 ** (1/3)
print(result) # 输出: 3.0
3. 负数次幂(倒数)
# 2的-1次方,等于 1/2
result = 2 ** -1
print(result) # 输出: 0.5
第二组:/
(真除法) vs //
(地板除法)
这一组是新手最容易踩坑的地方,也是 Python 2 和 Python 3 的一个重大区别。
/
(真除法 - True Division)
记住一条:在 Python 3 中,/
永远返回一个浮点数(float),无论它的操作数是不是整数。 它追求的是数学上的精确结果。
# 整数相除,结果也是浮点数
result = 10 / 3
print(result) # 输出: 3.3333333333333335
# 能整除,结果依然是浮点数
result = 6 / 2
print(result) # 输出: 3.0
# 浮点数运算
result = 7.0 / 2
print(result) # 输出: 3.5
为什么这么设计?
因为在很多科学计算和数据分析场景下,你需要的是精确的商。如果 10 / 3
返回 3
,精度就丢失了。Python 3 的这个设计避免了这种意外的精度损失。
//
(地板除法 - Floor Division)
记住两条:
- 它返回的结果是不大于真实商的最大整数。
- 它的结果类型取决于操作数:如果两个操作数都是整数,结果就是整数;如果其中一个是浮点数,结果就是浮点数。
1. 正数的地板除
对于正数,地板除的效果和“取整除”一样,就是直接砍掉小数部分。
result = 10 // 3
print(result) # 输出: 3 (因为 3 <= 3.333... < 4)
result = 6 // 2
print(result) # 输出: 3
2. 负数的地板除(关键!)
对于负数,地板除的行为就和直觉不一样了,它不是简单地砍掉小数,而是向负无穷方向取整。
result = -10 // 3
print(result) # 输出: -4
# 为什么是 -4 而不是 -3?
# 因为 -10 / 3 的真实商是 -3.333...
# “不大于” -3.333... 的最大整数是 -4,而不是 -3。
result = -5 // 2
print(result) # 输出: -3 (因为 -3 <= -2.5 < -2)
3. 浮点数的地板除
result = 10.0 // 3
print(result) # 输出: 3.0 (结果是浮点数)
result = -10.0 // 3
print(result) # 输出: -4.0 (结果是浮点数)
配套运算符:%
(取模/求余)
地板除 //
和取模 %
是一对好兄弟,它们满足以下关系:
a == (a // b) * b + (a % b)
这个关系在处理负数时尤其重要,可以帮助你理解为什么负数取模的结果是正的。
# 正数
print(10 % 3) # 输出: 1 (因为 10 = 3 * 3 + 1)
# 负数
print(-10 % 3) # 输出: 2
# 为什么是 2?
# 因为 -10 = (-4) * 3 + 2
# 这里 a // b 的结果是 -4,所以余数必须是 2 才能让等式成立。
总结表格
运算符 | 名称 | 描述 | 示例 | 结果 |
---|---|---|---|---|
* | 乘法 | 数学乘法,或序列重复 | 5 * 2 / "a"*3 | 10 / "aaa" |
** | 幂运算 | 计算乘方 | 2 ** 3 | 8 |
/ | 真除法 | 返回精确的浮点数商 | 10 / 4 | 2.5 |
// | 地板除 | 返回不大于商的最大整数 | 10 // 4 / -10 // 4 | 2 / -3 |
% | 取模 | 返回除法的余数 | 10 % 4 / -10 % 4 | 2 / 2 |
给老程序员的建议: | ||||
在写代码时,要有意识地根据你的需求选择运算符。 |
- 需要精确的小数结果?用
/
。 - 只需要整数部分,并且处理的是正数?用
//
很直观。 - 需要处理负数的整数除法?一定要小心
//
的行为,它永远是向负无穷取整。 - 需要计算幂?
**
是你的不二之选,简洁又强大。
理解这些细微差别,能让你写出更健壮、更符合预期的代码。