04 - 运算符与表达式
这章讲 Python 里各种各样的运算符。就是加减乘除那些,再加上比较、逻辑之类的。内容不算难,但细节挺多的,当手册看就行。
算术运算符
这些你应该在数学课上都学过,直接看例子:
python
print(10 + 3) # 13,加法
print(10 - 3) # 7,减法
print(10 * 3) # 30,乘法
print(10 / 3) # 3.3333333333333335,除法(结果是浮点数)
print(10 // 3) # 3,整除(只取整数部分)
print(10 % 3) # 1,取余数
print(10 ** 3) # 1000,幂运算(10的3次方)
几个需要注意的地方:
除法 / 的结果永远是浮点数,哪怕能整除:
python
print(10 / 2) # 5.0,注意是 5.0 不是 5
print(type(10 / 2)) # <class 'float'>
整除 // 是向下取整,不是截断:
python
print(7 // 2) # 3
print(-7 // 2) # -4,注意不是 -3
-7 / 2 = -3.5,向下取整就是 -4。这个在面试题里经常出现,很多人会答错。
取余 % 跟整除是对应的:
python
print(7 % 2) # 1
print(-7 % 2) # 1,注意不是 -1
取余在判断奇偶、循环计数这些场景特别常用:
python
# 判断一个数是不是偶数
num = 10
if num % 2 == 0:
print("偶数")
else:
print("奇数")
比较运算符
比较两个值的大小或是否相等,结果是 True 或 False:
python
print(5 == 5) # True,等于
print(5 != 3) # True,不等于
print(5 > 3) # True,大于
print(5 < 3) # False,小于
print(5 >= 5) # True,大于等于
print(5 <= 3) # False,小于等于
Python 有个很爽的特性------链式比较:
python
x = 5
print(1 < x < 10) # True,等价于 1 < x and x < 10
print(1 < x < 3) # False
print(10 > x > 3 > 0) # True
在别的语言里你得写 x > 1 and x < 10,Python 直接写 1 < x < 10 就行,跟数学里写的一样。
逻辑运算符
用来组合多个条件:and(与)、or(或)、not(非)。
python
age = 25
has_id = True
# and:两个都为 True 才是 True
print(age >= 18 and has_id) # True
# or:有一个为 True 就是 True
print(age < 18 or has_id) # True
# not:取反
print(not has_id) # False
短路求值
这个概念很重要。and 和 or 有一个特性:
and:如果第一个条件是False,就不会看第二个(因为结果肯定是 False)or:如果第一个条件是True,就不会看第二个(因为结果肯定是 True)
python
# 这里第二个条件不会被执行,因为第一个是 False
result = False and (1 / 0) # 不会报错!
# 这里第二个条件不会被执行,因为第一个是 True
result = True or (1 / 0) # 也不会报错!
这个特性实际用起来可以做安全的条件检查:
python
# 先检查列表是不是空的,再去取元素
if my_list and my_list[0] == "hello":
print("找到了")
如果列表是空的,my_list 就是 False,后面的 my_list[0] 就不会被执行,避免了索引越界的错误。
返回值的秘密
and 和 or 不一定返回 True 或 False,它们返回的是决定结果的那个值:
python
print(3 and 5) # 5(两个都为真,返回最后一个)
print(0 and 5) # 0(第一个为假,直接返回第一个)
print(3 or 5) # 3(第一个为真,直接返回第一个)
print(0 or 5) # 5(第一个为假,返回第二个)
print("" or "默认值") # "默认值"
所以 or 经常被用来设置默认值:
python
name = user_input or "匿名用户"
# 如果 user_input 是空字符串,name 就是"匿名用户"
赋值运算符
就是 = 加上各种算术运算的简写:
python
x = 10
x += 5 # x = x + 5,x 变成 15
x -= 3 # x = x - 3,x 变成 12
x *= 2 # x = x * 2,x 变成 24
x //= 5 # x = x // 5,x 变成 4
x %= 3 # x = x % 3,x 变成 1
x **= 3 # x = x ** 3,x 变成 1
这些没什么好说的,就是为了少写几个字。用多了就习惯了。
成员运算符
判断一个东西在不在另一个东西里面:in 和 not in。
python
fruits = ["苹果", "香蕉", "橘子"]
print("苹果" in fruits) # True
print("葡萄" not in fruits) # True
print("香蕉" not in fruits) # False
# 字符串也可以用
print("py" in "python") # True
print("java" in "python") # False
in 的用法非常直观,读起来就跟说英语一样。后面学了列表、字典之后会用得更多。
位运算符
这些是操作二进制的,平时用得不多,但面试有时候会问:
python
a = 5 # 二进制: 101
b = 3 # 二进制: 011
print(a & b) # 1,按位与:001
print(a | b) # 7,按位或:111
print(a ^ b) # 6,按位异或:110
print(~a) # -6,按位取反
print(a << 1) # 10,左移一位:1010
print(a >> 1) # 2,右移一位:10
实际开发中,位运算主要用在性能敏感的场景或者处理二进制数据的时候。一般业务代码里很少写。
运算符优先级
跟数学一样,Python 的运算符也有优先级。从高到低大致是:
** 幂运算
~ + - 按位取反、正负号
* / // % 乘除
+ - 加减
<< >> 位移
& 按位与
^ 按位异或
| 按位或
== != < > 比较
not 逻辑非
and 逻辑与
or 逻辑或
说实话这个表我也背不全。我写代码的原则是------不确定优先级就加括号。
python
# 不加括号,你能确定这是什么意思吗?
result = a + b << 2 & 0xFF
# 加了括号,一目了然
result = ((a + b) << 2) & 0xFF
加括号不丢人,代码能看懂比少写两个括号重要多了。
海象运算符(:=)
这个稍微高级一点,Python 3.8 才加入的。它允许你在表达式里同时赋值:
python
# 不用海象运算符
data = input("输入内容:")
if len(data) > 0:
print(f"你输入了 {len(data)} 个字符")
# 用海象运算符
if (n := len(input("输入内容:"))) > 0:
print(f"你输入了 {n} 个字符")
一个更实际的场景:
python
# 在 while 循环里读取数据
while (line := input(">>> ")) != "quit":
print(f"你输入了: {line}")
这个运算符用好了可以让代码更简洁,用不好反而会让代码更难读。初期不强制使用,等后面遇到合适的场景再说。
本章小结
- 算术运算符:
+ - * / // % **,注意/返回浮点数,//是向下取整 - 比较运算符:
== != > < >= <=,支持链式比较 - 逻辑运算符:
and or not,有短路求值特性 - 成员运算符:
in和not in,非常直观好用 - 不确定优先级就加括号,别硬记
- 海象运算符
:=可以在表达式中同时赋值
面试题
Q1:10 / 3、10 // 3、10 % 3 的结果分别是什么?
点击查看答案
10 / 3=3.3333333333333335(浮点除法)10 // 3=3(整除,向下取整)10 % 3=1(取余)
注意 -10 // 3 的结果是 -4 而不是 -3,因为整除是向下取整(向负无穷方向),不是向零取整。
Q2:and 和 or 的短路求值是什么意思?有什么实际用途?
点击查看答案
短路求值是指逻辑运算时,如果第一个操作数已经能确定结果,就不会计算第二个操作数。
A and B:如果 A 为假,直接返回 A,不计算 BA or B:如果 A 为真,直接返回 A,不计算 B
实际用途:
- 安全的属性/索引访问 :
if obj and obj.name,先检查 obj 不是 None 再访问属性 - 设置默认值 :
value = user_input or "default" - 延迟计算:把开销大的操作放在后面,前面的条件不满足就跳过
Q3:-7 // 2 的结果是什么?为什么不是 -3?
点击查看答案
结果是 -4。
Python 的整除 // 是向下取整(floor division),也就是向负无穷方向取整。-7 / 2 = -3.5,向下取整就是 -4。
很多其他语言(比如 C、Java)的整除是向零取整,所以 -7 / 2 在这些语言里是 -3。这是 Python 和其他语言的一个区别,面试经常考。
Q4:x = 5,表达式 1 < x < 10 的结果是什么?Python 是怎么处理的?
点击查看答案
结果是 True。
Python 会把 1 < x < 10 展开为 1 < x and x < 10,也就是 1 < 5 and 5 < 10,两个都是 True,所以结果是 True。
这是 Python 独有的链式比较语法,跟数学里的写法一致,比大多数语言更直观。注意 x 只会被计算一次。