运算符与优先级:Python里的“语法标点”和“先后顺序”

今天我们来学习一下python里的运算符以及优先级的规则及其用法;在前一天我们有了数据类型这些“食材”,接下来就得靠运算符把它们串起来,变成一道道“菜”。运算符就像是Python里的标点符号,决定了数据怎么组合、怎么比较。而优先级则决定了表达式里的“先来后到”,搞错了顺序,菜的味道可就全变了。


一、算术运算符:最基础的数学操作

这部分跟你小学学的数学差不多,就是多了几个编程特有的符号。

运算符描述例子(a=3, b=2)结果
+a + b5
-a - b1
*a * b6
/除(返回浮点数)a / b1.5
%取模(求余数)a % b1
**幂运算a ** b9
//整除(向下取整)a // b1

需要注意的两个坑:

  1. 负数取整和取模:Python的//向下取整,而不是直接截断小数部分。

    print(15 // 4)    # 3(15/4=3.75,向下取整为3)
    print(-15 // 4)   # -4(-15/4=-3.75,向下取整为-4,因为-4更小)
    print(15 % 4)     # 3(余数 = 15 - 3*4 = 3)
    print(-15 % 4)    # 1(余数 = -15 - (-4)*4 = 1)
    

    小贴士:记住一个规律 (a % b) + (-a % b) = b(当a不为0时),可以帮你快速验证结果。

  2. 科学计数法1e8 表示 (1 \times 10^8),类型是浮点数。


二、比较运算符:问出“是与否”

用来比较两个值,返回布尔值 TrueFalse

运算符描述
==等于
!=不等于
>大于
<小于
>=大于或等于
<=小于或等于
a, b = 20, 9
print(a == b)   # False
print(a != b)   # True
print(a > b)    # True

三、赋值运算符:给变量“贴标签”

除了最基础的 =,还有各种增强赋值,让代码更简洁。

1. 基本赋值与增强赋值

运算符等价写法
+=a = a + b
-=a = a - b
*=a = a * b
/=a = a / b
%=a = a % b
**=a = a ** b
//=a = a // b

2. 增强赋值 vs 普通赋值:一个容易忽略的效率问题

可变对象(比如列表)来说,增强赋值是在原地修改,而普通赋值是新建对象

# 普通赋值:新建列表,原列表不变
lis1 = [1, 2]
lis2 = lis1
lis1 = lis1 + [3, 4]
print(lis1)   # [1, 2, 3, 4]
print(lis2)   # [1, 2](不变)

# 增强赋值:原地修改,所有引用都受影响
lis1 = [1, 2]
lis2 = lis1
lis1 += [3, 4]
print(lis1)   # [1, 2, 3, 4]
print(lis2)   # [1, 2, 3, 4](也跟着变了)

实战建议:操作大列表时,优先用增强赋值,效率更高。但要小心副作用——如果你不希望原数据被改动,记得先拷贝一份。

3. 序列赋值

Python支持一次性给多个变量赋值,非常灵活:

a, b = 3, 4           # 等价于 (a, b) = (3, 4)
a, b, c = [3, 4, 5]   # 列表也能解包
a, b, c = "你好吗"     # 字符串解包成三个字符

4. 海象运算符 :=(Python 3.8+)

可以在表达式内部给变量赋值,省掉一行代码:

# 传统写法
length = len("hello")
print(length + 5)
print(f"长度为{length}")

# 海象写法
print((length := len("hello")) + 5)  # 赋值+使用一步到位
print(f"长度为{length}")

注意:记得加括号,否则会把整个表达式的值赋给变量,而不是你想要的结果。


四、逻辑运算符

用于布尔逻辑运算,返回不是单纯的True/False,而是决定结果的那个操作数(短路原则)。

运算符描述短路规则
and布尔“与”左边为假,返回左边;否则返回右边
or布尔“或”左边为真,返回左边;否则返回右边
not布尔“非”(返回布尔值)假→True,真→False
a, b, c, d = 2, "hello", [], 0

# and:左边为假就停
print(c and a)   # [](c是假,直接返回c)
print(a and b)   # "hello"(a是真,继续看b,返回b)

# or:左边为真就停
print(a or c)    # 2(a是真,直接返回a)
print(c or d)    # 0(c是假,继续看d,返回d)

# not:取反
print(not c)     # True

补充两个好用的内置函数

  • all(iterable):所有元素都为真,返回True(空容器也返回True
  • any(iterable):任一元素为真,返回True(空容器返回False

优先级not > and > or,记不住就加括号,可读性更好。


五、成员运算符

用于判断一个元素是否存在于容器中。

运算符描述
in在…中
not in不在…中
str1 = "hello world"
list1 = [1, 2, 3, 4, 5]
print("hello" in str1)   # True
print(6 not in list1)    # True

六、位运算符

位运算符把数字看作二进制进行按位操作,适合底层优化、权限控制、加密等场景。

运算符描述例子(a=60, b=13)
&按位与(同1为1)a & b = 12(0000 1100)
|按位或(有1为1)a | b = 61(0011 1101)
^按位异或(不同为1)a ^ b = 49(0011 0001)
~按位取反(含符号位)~a = -61
<<左移(右补0)a << 2 = 240
>>右移(左补符号位)a >> 2 = 15

一个有趣的特性:一个数异或同一个数两次,结果还是它自己(a ^ b ^ a == b),这在某些加密算法中很常用。

负数的位运算

负数在计算机中以补码形式存储,所以位运算时要注意:

print(-23 >> 2)   # -6
print(-23 << 2)   # -92

P.S.:日常开发中位运算用得不多,真遇到了,用 bin() 打印出二进制手动验证一下就好。


七、进制转换工具函数

函数描述例子
bin()转二进制字符串(带0b前缀)bin(3)'0b11'
oct()转八进制字符串(带0o前缀)oct(8)'0o10'
hex()转十六进制字符串(带0x前缀)hex(255)'0xff'

八、序列的连接操作:++=* 的“跨界”用法

这几个运算符不光能算数,还能操作序列(字符串、列表、元组)。

# 字符串拼接
print("1" + "2")        # "12"

# 列表拼接(类型必须一致)
print([1, 2] + [3, 4])  # [1, 2, 3, 4]

# 元组拼接
print((1, 2) + (3, 4))  # (1, 2, 3, 4)

# 重复操作
print("ha" * 3)         # "hahaha"
print([0] * 3)          # [0, 0, 0]

注意:不同类型不能直接用+拼接,比如 "1" + [2, 3] 会报错。


九、运算符优先级:到底先算谁?

记住一条黄金法则:不确定就用括号。括号优先级最高,能保证你的意图被正确执行。

常用优先级从高到低(想细看的可以对照PDF里的完整表格):

优先级(高→低)运算符
最高**
~(按位取反)
* / % //
+ -
<< >>
&
^ |
<= < > >=
== !=
= += -= 等(赋值运算符)
is is not
in not in
最低not and or

收尾

运算符就像做菜时的“刀工”和“火候”——光有食材还不够,得知道怎么切、怎么炒、先放哪样后放哪样。算术、比较、逻辑、赋值这四大类是日常用得最多的,把它们玩熟了,你的代码就能写得又快又稳。

至于位运算和复杂的优先级,不需要死记硬背,用的时候查一下,写代码时多用括号把意图明确表达出来,比什么都强。

如果说非要给您一个什么样子的建议,那我的建议是:代码是写给“下一个看它的人”看的,包括未来的你自己。 多用括号,多写清晰易懂的表达式,比追求“一行炫技”重要得多。

下图为本文知识点的思维导图(示意):
在这里插入图片描述

感谢阅读,祝你编码愉快!有任何疑问,随时欢迎来聊。

更多推荐