三. 运算符(全解)
3.1 算术运算符
先看一段代码,这里面有几个值得注意的细节:
# 注意:除法结果总是浮点数,即使能整除
print(10 / 2) # 5.0
# 整除向负无穷取整
print(-5 // 2) # -3 (因为 -2.5 向下取整为 -3)
# 取余公式:a = (a//b)*b + (a%b)
print(-5 % 2) # 1 (很多新手困惑,其实余数非负)
需要特别留意的是:Python 中除法运算的结果始终是浮点数,即使两个整数恰好整除。此外,负数的整除采用向下取整方式,而不是向零取整,因此 -5 // 2 得到 -3。取余运算遵循公式 a = (a//b)*b + (a%b),这意味着余数一定为非负数——这个特性常常让初学者感到困惑。
3.2 比较运算符(返回布尔值)
a, b = 5, 7
print(a == b) # False 相等
print(a != b) # True 不等
print(a < b) # True
print(a > b) # False
print(a <= 5) # True
print(b >= 7) # True
# 字符串比较按字典序(Unicode码点)
print("apple" < "banana") # True
print("Zoo" < "apple") # True,因为大写字母 Z 的码点小于 a
比较运算符返回的是布尔值,这一点非常直观。但字符串比较是按字典序(实际上是 Unicode 码点)进行的,大写字母的码点普遍小于小写字母,因此 "Zoo" 会排在 "apple" 前面。
3.3 逻辑运算符(and, or, not)
age = 20
has_license = True
# and:两边都为True才返回True
if age >= 18 and has_license:
print("可以开车")
# or:至少一个True即为True
if age < 18 or has_license:
print("可能是年轻人或老司机")
# not:取反
is_student = False
if not is_student:
print("不是学生")
# 短路逻辑:and 左边为False则右边不计算;or 左边为True则右边不计算
def risky():
raise Exception("不会执行")
False and risky() # 安全,risky不会被调用
True or risky() # 安全,risky不会被调用
逻辑运算符的短路特性是一个非常实用的技巧:当 and 左边为 False 时,右边的表达式根本不会执行;or 左边为 True 时,右边同样被跳过。利用这一特性可以有效避免不必要的错误调用。
3.4 赋值运算符与复合赋值
x = 10
x += 5 # 等价 x = x + 5
x -= 3 # x = x - 3
x *= 2
x /= 4 # 注意:除法后变为浮点数
x //= 2
x %= 3
x **= 2
# 海象运算符(Python 3.8+):在表达式中赋值
if (n := len([1, 2, 3])) > 2:
print(f"列表长度 {n} 大于2")
复合赋值运算符能让代码更为简洁,但需要留意:除法赋值后变量的类型会变为浮点数。Python 3.8 引入的海象运算符(:=)允许在表达式内部进行赋值,非常适合在条件判断中同时计算并保存结果。
3.5 位运算符(基础了解)
a = 0b1010 # 二进制 10
b = 0b1100 # 二进制 12
print(a & b) # 按位与 0b1000 -> 8
print(a | b) # 按位或 0b1110 -> 14
print(a ^ b) # 按位异或 0b0110 -> 6
print(~a) # 按位取反(无限位) -> -11 (补码)
print(a << 1) # 左移一位 -> 20
print(a >> 1) # 右移一位 -> 5
位运算符在日常开发中使用频率不高,但理解它们有助于处理底层数据或进行性能优化。按位取反的结果采用补码表示,因此 ~a 得到 -11,有兴趣可以自行演算验证。
四. 输入与输出
4.1 基本输入输出
# input() 永远返回字符串
name = input("请输入你的名字:")
print("你好," + name)
# 输入数字需要转换
age_str = input("年龄:")
age = int(age_str) # 可能抛出 ValueError
input() 函数的一个重要特点:无论用户输入什么内容,返回的始终是字符串。若要获取数字,必须手动进行类型转换,这一步很容易出错——如果用户输入了非法的数字格式,就会抛出 ValueError 异常。
4.2 格式化输出的三种方式
方法一:% 格式化(旧风格)
name = "小明"
score = 92.5
print("姓名:%s,成绩:%.1f" % (name, score))
方法二:.format() 方法
print("姓名:{},成绩:{:.1f}".format(name, score))
print("成绩:{1:.1f},姓名:{0}".format(name, score)) # 指定位置
方法三:f-string(Python 3.6+,最推荐)
print(f"姓名:{name},成绩:{score:.1f}")
print(f"2 + 3 = {2 + 3}")
print(f"{name:>10}") # 右对齐,宽度10
三种格式化输出方式中,f-string 最为直观且性能最佳,目前已成为主流选择。% 格式化和 .format() 在维护旧代码时仍会遇到,但新项目强烈推荐直接使用 f-string。
4.3 控制 print 的结尾与分隔符
print("A", end="") # 不换行
print("B") # 输出 "AB"
print(1, 2, 3, sep="-") # 1-2-3
print 函数的 end 和 sep 参数非常实用:end 默认是换行符,将其改为空字符串可以实现连续输出;sep 用来控制多个参数之间的分隔符,默认为空格。
