Python 基础:常用运算符介绍 (带演示)
引言
在编程的世界里,运算符是执行各种操作的基石,它们就像语言中的动词,告诉计算机要对数据做什么。无论是进行简单的数学计算、比较数值的大小、判断条件的真假,还是更复杂的数据处理,都离不开运算符的身影。
Python 语言提供了丰富多样的运算符,它们作用于变量和值,执行特定的运算并返回结果。对于初学者来说,熟练掌握这些基本运算符是迈向Python编程的关键一步。
本文将详细介绍 Python 中最常用的一些运算符,包括它们的分类、作用、使用方法,并提供丰富的代码示例进行演示,帮助你深入理解这些重要的概念。
1. 算术运算符 (Arithmetic Operators)
算术运算符用于执行常见的数学运算,如加、减、乘、除等。它们是编程中最基础也是最常用的一类运算符。
运算符 | 名称 | 描述 | 示例 | 结果 |
---|---|---|---|---|
+ |
加法 | 将两个操作数相加 | a + b |
a 和 b 的和 |
- |
减法 | 第一个操作数减去第二个操作数 | a - b |
a 和 b 的差 |
* |
乘法 | 两个操作数相乘 | a * b |
a 和 b 的积 |
/ |
除法 | 第一个操作数除以第二个操作数 | a / b |
a 和 b 的商 |
// |
整除 | 第一个操作数除以第二个操作数,返回商的整数部分(向下取整) | a // b |
商的整数部分 |
% |
取模 | 返回除法的余数 | a % b |
除法的余数 |
** |
幂运算 | 第一个操作数的第二个操作数次幂 | a ** b |
a 的 b 次幂 |
接下来,我们通过代码示例来演示这些算术运算符的使用:
“`python
定义两个变量
a = 10
b = 3
print(f”a = {a}”)
print(f”b = {b}”)
print(“-” * 20) # 分隔线
加法 (+)
sum_result = a + b
print(f”{a} + {b} = {sum_result}”) # 输出: 10 + 3 = 13
减法 (-)
difference_result = a – b
print(f”{a} – {b} = {difference_result}”) # 输出: 10 – 3 = 7
乘法 (*)
product_result = a * b
print(f”{a} * {b} = {product_result}”) # 输出: 10 * 3 = 30
除法 (/)
注意:在 Python 3 中,除法结果总是浮点数
division_result = a / b
print(f”{a} / {b} = {division_result}”) # 输出: 10 / 3 = 3.333…
整除 (//)
向下取整,结果是整数
floor_division_result = a // b
print(f”{a} // {b} = {floor_division_result}”) # 输出: 10 // 3 = 3
整除与负数
x = -10
y = 3
print(f”{x} // {y} = {x // y}”) # 输出: -10 // 3 = -4 (注意:向负无穷方向取整)
print(f”{a} // -{b} = {a // -b}”) # 输出: 10 // -3 = -4 (注意:向负无穷方向取整)
取模 (%)
返回除法的余数
modulo_result = a % b
print(f”{a} % {b} = {modulo_result}”) # 输出: 10 % 3 = 1
取模与负数
余数的符号与除数(右边的操作数)相同
print(f”{x} % {y} = {x % y}”) # 输出: -10 % 3 = 2 (-10 = -4 * 3 + 2)
print(f”{a} % -{b} = {a % -b}”) # 输出: 10 % -3 = -2 (10 = -4 * -3 + -2)
幂运算 (**)
power_result = a ** b # 10 的 3 次幂
print(f”{a} ** {b} = {power_result}”) # 输出: 10 ** 3 = 1000
浮点数的幂运算 (开方)
sqrt_result = 9 ** 0.5 # 9 的 0.5 次幂,即平方根
print(f”9 ** 0.5 = {sqrt_result}”) # 输出: 9 ** 0.5 = 3.0
结合不同类型进行算术运算
整数和浮点数运算的结果通常是浮点数
int_var = 5
float_var = 2.5
mixed_sum = int_var + float_var
print(f”{int_var} + {float_var} = {mixed_sum}”) # 输出: 5 + 2.5 = 7.5
字符串和整数的乘法 (重复字符串)
string_var = “Hello”
repeat_result = string_var * 3
print(f'”{string_var}” * 3 = “{repeat_result}”‘) # 输出: “Hello” * 3 = “HelloHelloHello”
字符串的加法 (拼接字符串)
string1 = “Hello”
string2 = ” World”
concatenation_result = string1 + string2
print(f'”{string1}” + “{string2}” = “{concatenation_result}”‘) # 输出: “Hello” + ” World” = “Hello World”
注意:不能对不同类型进行不兼容的算术运算,例如数字和字符串相加会引发 TypeError
print(10 + “Hello”) # 这行代码会报错!
“`
总结: 算术运算符是进行数值计算的基础。需要特别注意 /
除法的结果是浮点数,//
整除是向下取整,以及 %
取模在涉及负数时的行为。同时,一些算术运算符 (+
, *
) 也可以用于特定非数值类型(如字符串和列表)来执行拼接或重复操作。
2. 比较运算符 (Comparison Operators / Relational Operators)
比较运算符用于比较两个值,它们总是返回一个布尔值 (True
或 False
),表示比较的结果是否为真。
运算符 | 名称 | 描述 | 示例 | 结果 |
---|---|---|---|---|
== |
相等 | 如果两个操作数相等,则为 True | a == b |
True 或 False |
!= |
不相等 | 如果两个操作数不相等,则为 True | a != b |
True 或 False |
> |
大于 | 如果左边的操作数大于右边的操作数,则为 True | a > b |
True 或 False |
< |
小于 | 如果左边的操作数小于右边的操作数,则为 True | a < b |
True 或 False |
>= |
大于或等于 | 如果左边的操作数大于或等于右边的操作数,则为 True | a >= b |
True 或 False |
<= |
小于或等于 | 如果左边的操作数小于或等于右边的操作数,则为 True | a <= b |
True 或 False |
比较运算符常用于条件判断语句(如 if
语句)和循环语句中。
“`python
定义变量进行比较
a = 10
b = 20
c = 10
d = “Hello”
e = “hello”
print(f”a = {a}, b = {b}, c = {c}, d = ‘{d}’, e = ‘{e}'”)
print(“-” * 20)
相等 (==)
print(f”{a} == {b} ? {a == b}”) # 输出: 10 == 20 ? False
print(f”{a} == {c} ? {a == c}”) # 输出: 10 == 10 ? True
print(f”{d} == {e} ? {d == e}”) # 输出: Hello == hello ? False (字符串比较区分大小写)
不相等 (!=)
print(f”{a} != {b} ? {a != b}”) # 输出: 10 != 20 ? True
print(f”{a} != {c} ? {a != c}”) # 输出: 10 != 10 ? False
print(f”{d} != {e} ? {d != e}”) # 输出: Hello != hello ? True
大于 (>)
print(f”{a} > {b} ? {a > b}”) # 输出: 10 > 20 ? False
print(f”{b} > {a} ? {b > a}”) # 输出: 20 > 10 ? True
小于 (<)
print(f”{a} < {b} ? {a < b}”) # 输出: 10 < 20 ? True
print(f”{b} < {a} ? {b < a}”) # 输出: 20 < 10 ? False
大于或等于 (>=)
print(f”{a} >= {c} ? {a >= c}”) # 输出: 10 >= 10 ? True
print(f”{a} >= {b} ? {a >= b}”) # 输出: 10 >= 20 ? False
小于或等于 (<=)
print(f”{a} <= {c} ? {a <= c}”) # 输出: 10 <= 10 ? True
print(f”{a} <= {b} ? {a <= b}”) # 输出: 10 <= 20 ? True
比较不同类型 (通常会失败或有意外结果)
print(a > d) # 这行代码会报错,数字和字符串不能直接比较大小
比较列表或元组 (按元素顺序比较)
list1 = [1, 2, 3]
list2 = [1, 2, 4]
list3 = [1, 2, 3]
print(f”{list1} == {list3} ? {list1 == list3}”) # 输出: [1, 2, 3] == [1, 2, 3] ? True (值相等)
print(f”{list1} < {list2} ? {list1 < list2}”) # 输出: [1, 2, 3] < [1, 2, 4] ? True (比较到第三个元素 3 < 4)
链式比较
Python 允许链式比较,例如 a < b < c 等价于 (a < b) and (b < c)
x = 15
print(f”{a} < {x} < {b} ? {a < x < b}”) # 输出: 10 < 15 < 20 ? True (因为 10 < 15 为 True 且 15 < 20 为 True)
print(f”{a} < {b} < {c} ? {a < b < c}”) # 输出: 10 < 20 < 10 ? False (因为 20 < 10 为 False)
“`
总结: 比较运算符用于判断值之间的关系。==
用于判断值是否相等,is
用于判断是否是同一个对象(后续会介绍)。理解链式比较是 Python 的一个方便特性。注意不同类型之间通常不能直接进行大小比较。
3. 赋值运算符 (Assignment Operators)
赋值运算符用于将值赋给变量。最基本的赋值运算符是 =
。此外,Python 还提供了一系列复合赋值运算符,可以将算术或其他运算与赋值结合起来,使代码更简洁。
运算符 | 示例 | 等价于 | 描述 |
---|---|---|---|
= |
a = 1 |
简单的赋值 | |
+= |
a += b |
a = a + b |
加法赋值 |
-= |
a -= b |
a = a - b |
减法赋值 |
*= |
a *= b |
a = a * b |
乘法赋值 |
/= |
a /= b |
a = a / b |
除法赋值 |
//= |
a //= b |
a = a // b |
整除赋值 |
%= |
a %= b |
a = a % b |
取模赋值 |
**= |
a **= b |
a = a ** b |
幂运算赋值 |
&= |
a &= b |
a = a & b |
按位与赋值 |
|= |
a |= b |
a = a | b |
按位或赋值 |
^= |
a ^= b |
a = a ^ b |
按位异或赋值 |
>>= |
a >>= b |
a = a >> b |
按位右移赋值 |
<<= |
a <<= b |
a = a << b |
按位左移赋值 |
复合赋值运算符的使用示例如下:
“`python
简单赋值
x = 10
print(f”初始值 x = {x}”) # 输出: 初始值 x = 10
加法赋值 (+=)
x += 5 # 等价于 x = x + 5
print(f”x += 5 后, x = {x}”) # 输出: x += 5 后, x = 15
减法赋值 (-=)
x -= 3 # 等价于 x = x – 3
print(f”x -= 3 后, x = {x}”) # 输出: x -= 3 后, x = 12
乘法赋值 (*=)
x = 2 # 等价于 x = x * 2
print(f”x = 2 后, x = {x}”) # 输出: x *= 2 后, x = 24
除法赋值 (/=)
注意:结果会变成浮点数
x /= 4 # 等价于 x = x / 4
print(f”x /= 4 后, x = {x}”) # 输出: x /= 4 后, x = 6.0
整除赋值 (//=)
y = 10
y //= 3 # 等价于 y = y // 3
print(f”y = 10, y //= 3 后, y = {y}”) # 输出: y = 10, y //= 3 后, y = 3
取模赋值 (%=)
z = 10
z %= 3 # 等价于 z = z % 3
print(f”z = 10, z %= 3 后, z = {z}”) # 输出: z = 10, z %= 3 后, z = 1
幂运算赋值 (**=)
p = 2
p = 3 # 等价于 p = p ** 3
print(f”p = 2, p = 3 后, p = {p}”) # 输出: p = 2, p **= 3 后, p = 8
复合赋值也适用于其他类型,例如字符串拼接
greeting = “Hello”
greeting += ” World”
print(f’greeting += ” World” 后, greeting = “{greeting}”‘) # 输出: greeting += ” World” 后, greeting = “Hello World”
列表的扩展
my_list = [1, 2]
my_list += [3, 4] # 等价于 my_list = my_list + [3, 4]
print(f”my_list = [1, 2], my_list += [3, 4] 后, my_list = {my_list}”) # 输出: my_list = [1, 2], my_list += [3, 4] 后, my_list = [1, 2, 3, 4]
注意:某些操作符不能用于所有类型,例如乘法赋值对列表是重复元素
my_list_2 = [1, 2]
my_list_2 = 2 # 等价于 my_list_2 = my_list_2 * 2
print(f”my_list_2 = [1, 2], my_list_2 = 2 后, my_list_2 = {my_list_2}”) # 输出: my_list_2 = [1, 2], my_list_2 *= 2 后, my_list_2 = [1, 2, 1, 2]
按位赋值将在下一节的按位运算符中演示
“`
总结: 赋值运算符用于给变量赋予新的值。复合赋值运算符提供了一种简洁的方式来执行操作并更新变量的值,是日常编程中非常常用的语法糖。
4. 逻辑运算符 (Logical Operators)
逻辑运算符用于组合或修改布尔表达式。它们通常用于 if
语句、while
循环以及其他需要进行条件判断的场景。Python 的逻辑运算符是英文单词:and
, or
, not
。
运算符 | 名称 | 描述 | 示例 | 结果 |
---|---|---|---|---|
and |
逻辑与 | 如果两个操作数都为 True,则结果为 True | x and y |
如果 x 和 y 都为 True,则为 True |
or |
逻辑或 | 如果两个操作数中至少一个为 True,则结果为 True | x or y |
如果 x 或 y 中至少一个为 True,则为 True |
not |
逻辑非 | 反转操作数的布尔值 | not x |
如果 x 为 True,则为 False;反之亦然 |
逻辑运算符具有”短路(Short-circuit)”特性:
- 对于
and
运算符,如果第一个操作数为False
,则不再评估第二个操作数,直接返回False
。 - 对于
or
运算符,如果第一个操作数为True
,则不再评估第二个操作数,直接返回True
。
此外,Python 中的任何对象都可以被视为布尔值:
* False
、None
、数字 0
(包括整数、浮点数、复数)、空序列 (空字符串 ""
, 空列表 []
, 空元组 ()
, 空字典 {}
), 空集合 set()
都被视为 False
。
* 其他所有值都被视为 True
。
“`python
定义布尔变量
is_sunny = True
is_warm = False
print(f”is_sunny = {is_sunny}, is_warm = {is_warm}”)
print(“-” * 20)
逻辑与 (and)
只有两个条件都为 True 时,结果才为 True
print(f”is_sunny and is_warm ? {is_sunny and is_warm}”) # 输出: is_sunny and is_warm ? False
print(f”True and True ? {True and True}”) # 输出: True and True ? True
print(f”False and True ? {False and True}”) # 输出: False and True ? False
逻辑或 (or)
只要有一个条件为 True 时,结果就为 True
print(f”is_sunny or is_warm ? {is_sunny or is_warm}”) # 输出: is_sunny or is_warm ? True
print(f”False or False ? {False or False}”) # 输出: False or False ? False
print(f”True or False ? {True or False}”) # 输出: True or False ? True
逻辑非 (not)
反转布尔值
print(f”not is_sunny ? {not is_sunny}”) # 输出: not is_sunny ? False
print(f”not is_warm ? {not is_warm}”) # 输出: not is_warm ? True
逻辑运算符与非布尔值的结合 (利用对象的布尔值)
字符串 “Hello” 被视为 True,空字符串 “” 被视为 False
str1 = “Hello”
str2 = “”
print(f'”{str1}” and “{str2}” ? {“Hello” and “”}’) # 输出: “Hello” and “” ? (短路,返回 “”,其布尔值为 False)
print(f'”{str1}” or “{str2}” ? {“Hello” or “”}’) # 输出: “Hello” or “” ? Hello (短路,返回 “Hello”,其布尔值为 True)
print(f'”{str2}” or “{str1}” ? {“” or “Hello”}’) # 输出: “” or “Hello” ? Hello
数字 10 被视为 True, 数字 0 被视为 False
num1 = 10
num2 = 0
print(f”{num1} and {num2} ? {10 and 0}”) # 输出: 10 and 0 ? 0 (返回 0,其布尔值为 False)
print(f”{num1} or {num2} ? {10 or 0}”) # 输出: 10 or 0 ? 10 (返回 10,其布尔值为 True)
短路特性演示
下面的代码不会引发除零错误,因为 False and 0 / 0 的第一个操作数是 False,and 运算符发生短路
print(f”False and (1 / 0) ? {False and (1 / 0)}”) # 输出: False and (1 / 0) ? False (不会报错)
下面的代码也不会引发除零错误,因为 True or 0 / 0 的第一个操作数是 True,or 运算符发生短路
print(f”True or (1 / 0) ? {True or (1 / 0)}”) # 输出: True or (1 / 0) ? True (不会报错)
如果第一个操作数不足以决定结果,则会评估第二个操作数
print(f”True and (1 / 0) ? {True and (1 / 0)}”) # 这行代码会报错,因为 True and 需要评估第二个操作数
“`
总结: 逻辑运算符用于组合和反转布尔值或具有布尔意义的对象。理解 and
, or
, not
的行为以及短路特性对于编写条件逻辑至关重要。记住 Python 中哪些值被视为 False
也非常有用。
5. 位运算符 (Bitwise Operators)
位运算符直接操作整数的二进制位。对于初学者来说,这部分内容可能不如前几类常用,但在处理底层数据、进行高效计算或某些特定算法时非常有用。要理解位运算符,你需要先了解整数如何以二进制形式表示。
我们以 10 (二进制 1010
) 和 4 (二进制 0100
) 为例进行演示。
运算符 | 名称 | 描述 | 示例 | 结果(十进制) | 二进制演示 |
---|---|---|---|---|---|
& |
按位与 | 对应位都为 1 时,结果位才为 1 | x & y |
10 & 4 = 0 |
1010 & 0100 = 0000 |
| |
按位或 | 对应位有一个为 1 时,结果位就为 1 | x | y |
10 | 4 = 14 |
1010 | 0100 = 1110 |
^ |
按位异或 | 对应位不同时,结果位才为 1 | x ^ y |
10 ^ 4 = 14 |
1010 ^ 0100 = 1110 |
~ |
按位取反 | 对每一个二进制位取反 (0 变 1,1 变 0) | ~x |
~10 = -11 |
复杂,涉及补码 |
<< |
左移 | 将二进制位向左移动指定的位数,右侧补 0,相当于乘以 2 的幂 | x << n |
10 << 1 = 20 |
1010 << 1 = 10100 |
>> |
右移 | 将二进制位向右移动指定的位数,左侧补符号位(正数补 0),相当于整除以 2 的幂 | x >> n |
10 >> 1 = 5 |
1010 >> 1 = 0101 |
注意: 按位取反 ~x
的结果在 Python 中是 -(x+1)
,这涉及到二进制补码表示法,对于初学者可能较难理解。在大多数情况下,记住 ~x
的结果是 -(x+1)
即可。
“`python
定义整数变量
a = 10 # 二进制: 1010
b = 4 # 二进制: 0100
c = 5 # 二进制: 0101
print(f”a = {a} (binary: {a:0>4b})”) # {a:0>4b} 格式化输出为4位二进制,左侧补0
print(f”b = {b} (binary: {b:0>4b})”)
print(f”c = {c} (binary: {c:0>4b})”)
print(“-” * 20)
按位与 (&)
1010 & 0100 = 0000 (0)
bitwise_and_result = a & b
print(f”{a} & {b} = {bitwise_and_result} (binary: {bitwise_and_result:0>4b})”) # 输出: 10 & 4 = 0 (binary: 0000)
1010 & 0101 = 0000 (0) 错了,应该是 0000 (0) 与 0101 (5) -> 0000
1010 & 0101 = 0000 (0) 这个例子是错的。应该是 1010 & 0101 -> 0000
1010 (10) & 0101 (5) = 0000 (0)
bitwise_and_result_2 = a & c
print(f”{a} & {c} = {bitwise_and_result_2} (binary: {bitwise_and_result_2:0>4b})”) # 输出: 10 & 5 = 0 (binary: 0000)
按位或 (|)
1010 | 0100 = 1110 (14)
bitwise_or_result = a | b
print(f”{a} | {b} = {bitwise_or_result} (binary: {bitwise_or_result:0>4b})”) # 输出: 10 | 4 = 14 (binary: 1110)
1010 | 0101 = 1111 (15)
bitwise_or_result_2 = a | c
print(f”{a} | {c} = {bitwise_or_result_2} (binary: {bitwise_or_result_2:0>4b})”) # 输出: 10 | 5 = 15 (binary: 1111)
按位异或 (^)
1010 ^ 0100 = 1110 (14)
bitwise_xor_result = a ^ b
print(f”{a} ^ {b} = {bitwise_xor_result} (binary: {bitwise_xor_result:0>4b})”) # 输出: 10 ^ 4 = 14 (binary: 1110)
1010 ^ 0101 = 1111 (15)
bitwise_xor_result_2 = a ^ c
print(f”{a} ^ {c} = {bitwise_xor_result_2} (binary: {bitwise_xor_result_2:0>4b})”) # 输出: 10 ^ 5 = 15 (binary: 1111)
按位取反 (~)
~10 的结果是 -(10+1) = -11
bitwise_not_result = ~a
print(f”~{a} = {bitwise_not_result}”) # 输出: ~10 = -11
左移 (<<)
10 (1010) 左移 1 位 -> 10100 (20)
left_shift_result = a << 1
print(f”{a} << 1 = {left_shift_result} (binary: {left_shift_result:b})”) # 输出: 10 << 1 = 20 (binary: 10100)
10 (1010) 左移 2 位 -> 101000 (40)
left_shift_result_2 = a << 2
print(f”{a} << 2 = {left_shift_result_2} (binary: {left_shift_result_2:b})”) # 输出: 10 << 2 = 40 (binary: 101000)
右移 (>>)
10 (1010) 右移 1 位 -> 0101 (5)
right_shift_result = a >> 1
print(f”{a} >> 1 = {right_shift_result} (binary: {right_shift_result:b})”) # 输出: 10 >> 1 = 5 (binary: 101)
10 (1010) 右移 2 位 -> 0010 (2)
right_shift_result_2 = a >> 2
print(f”{a} >> 2 = {right_shift_result_2} (binary: {right_shift_result_2:b})”) # 输出: 10 >> 2 = 2 (binary: 10)
位运算符的复合赋值
num = 7 # 二进制 0111
num &= 3 # 等价于 num = num & 3 (0111 & 0011 = 0011)
print(f”7 &= 3 后 num = {num}”) # 输出: 7 &= 3 后 num = 3
num = 7 # 二进制 0111
num |= 10 # 等价于 num = num | 10 (0111 | 1010 = 1111)
print(f”7 |= 10 后 num = {num}”) # 输出: 7 |= 10 后 num = 15
“`
总结: 位运算符直接操作数据的二进制表示。它们在处理标志位、数据编码、或者需要进行位级别操作的场景中非常有用。虽然对于日常应用可能不太常用,但了解它们的工作原理有助于深入理解计算机如何处理数据。
6. 成员运算符 (Membership Operators)
成员运算符用于测试序列(如字符串、列表、元组)或集合中是否包含某个特定的值。
运算符 | 名称 | 描述 | 示例 | 结果 |
---|---|---|---|---|
in |
成员 | 如果在指定的序列中找到值,则为 True | x in sequence |
True 或 False |
not in |
非成员 | 如果在指定的序列中没有找到值,则为 True | x not in sequence |
True 或 False |
“`python
定义序列
my_list = [1, 2, 3, 4, 5]
my_string = “Hello Python”
my_tuple = (10, 20, 30)
my_dict = {‘a’: 1, ‘b’: 2, ‘c’: 3} # 对于字典,in/not in 默认检查键(key)
print(f”my_list = {my_list}”)
print(f’my_string = “{my_string}”‘)
print(f”my_tuple = {my_tuple}”)
print(f”my_dict = {my_dict}”)
print(“-” * 20)
检查元素是否在列表中 (in)
print(f”3 in my_list ? {3 in my_list}”) # 输出: 3 in my_list ? True
print(f”6 in my_list ? {6 in my_list}”) # 输出: 6 in my_list ? False
检查子字符串是否在字符串中 (in)
print(f'”Python” in my_string ? {“Python” in my_string}’) # 输出: “Python” in my_string ? True
print(f'”Java” in my_string ? {“Java” in my_string}’) # 输出: “Java” in my_string ? False
print(f'”hello” in my_string ? {“hello” in my_string}’) # 输出: “hello” in my_string ? False (in 区分大小写)
检查元素是否不在列表中 (not in)
print(f”6 not in my_list ? {6 not in my_list}”) # 输出: 6 not in my_list ? True
print(f”3 not in my_list ? {3 not in my_list}”) # 输出: 3 not in my_list ? False
检查元素是否在元组中 (in)
print(f”20 in my_tuple ? {20 in my_tuple}”) # 输出: 20 in my_tuple ? True
print(f”40 in my_tuple ? {40 in my_tuple}”) # 输出: 40 in my_tuple ? False
检查键是否在字典中 (in)
print(f”‘a’ in my_dict ? {‘a’ in my_dict}”) # 输出: ‘a’ in my_dict ? True (检查键 ‘a’)
print(f”‘z’ in my_dict ? {‘z’ in my_dict}”) # 输出: ‘z’ in my_dict ? False (检查键 ‘z’)
检查值是否在字典中 (需要使用 values() 方法)
print(f”1 in my_dict.values() ? {1 in my_dict.values()}”) # 输出: 1 in my_dict.values() ? True (检查值 1)
print(f”5 in my_dict.values() ? {5 in my_dict.values()}”) # 输出: 5 in my_dict.values() ? False (检查值 5)
“`
总结: 成员运算符 in
和 not in
提供了方便快捷的方式来检查一个元素是否存在于一个集合中,这对于数据查找和条件判断非常实用。
7. 身份运算符 (Identity Operators)
身份运算符用于比较两个变量是否引用了同一个对象(即它们是否指向同一个内存地址),而不是简单地比较它们的值是否相等。
运算符 | 名称 | 描述 | 示例 | 结果 |
---|---|---|---|---|
is |
是 | 如果两个变量引用同一个对象,则为 True | x is y |
True 或 False |
is not |
不是 | 如果两个变量不引用同一个对象,则为 True | x is not y |
True 或 False |
重要区别:is
vs ==
is
比较的是两个变量所指向的对象的身份(ID),即内存地址。==
比较的是两个变量所指向的对象的值。
对于不可变类型(如整数、字符串、元组),Python 有时会出于优化目的,让具有相同值的变量指向同一个对象(称为”interning” 或 “缓存”)。但这并不可靠,特别是对于大数字或动态生成的字符串。对于可变类型(如列表、字典、集合),即使它们的值完全相同,通常也会创建新的对象,因此 is
的结果会是 False
。
“`python
比较数值 (小整数会被缓存)
a = 10
b = 10
c = 20
print(f”a = {a}, b = {b}, c = {c}”)
print(“-” * 20)
值比较
print(f”a == b ? {a == b}”) # 输出: a == b ? True (值相等)
print(f”a == c ? {a == c}”) # 输出: a == c ? False (值不相等)
身份比较 (对于小整数,a 和 b 可能指向同一个对象)
print(f”a is b ? {a is b}”) # 输出: a is b ? True (通常对于 -5 到 256 的整数是 True)
print(f”a is c ? {a is c}”) # 输出: a is c ? False
比较字符串 (短字符串可能被缓存)
str1 = “hello”
str2 = “hello”
str3 = “world”
str4 = “he” + “llo” # 动态拼接的字符串,结果值相同
print(f’str1 = “{str1}”, str2 = “{str2}”, str3 = “{str3}”, str4 = “{str4}”‘)
print(“-” * 20)
值比较
print(f”str1 == str2 ? {str1 == str2}”) # 输出: str1 == str2 ? True
print(f”str1 == str3 ? {str1 == str3}”) # 输出: str1 == str3 ? False
print(f”str1 == str4 ? {str1 == str4}”) # 输出: str1 == str4 ? True
身份比较 (短字符串可能被缓存,动态拼接的不一定)
print(f”str1 is str2 ? {str1 is str2}”) # 输出: str1 is str2 ? True (通常是 True)
print(f”str1 is str3 ? {str1 is str3}”) # 输出: str1 is str3 ? False
print(f”str1 is str4 ? {str1 is str4}”) # 输出: str1 is str4 ? True (Python 优化,会识别并缓存)
比较列表 (可变类型,即使值相同,通常不是同一个对象)
list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = list1 # 让 list3 引用 list1 指向的同一个对象
print(f”list1 = {list1}, list2 = {list2}, list3 = {list3}”)
print(“-” * 20)
值比较
print(f”list1 == list2 ? {list1 == list2}”) # 输出: list1 == list2 ? True (值相等)
print(f”list1 == list3 ? {list1 == list3}”) # 输出: list1 == list3 ? True (值相等)
身份比较
print(f”list1 is list2 ? {list1 is list2}”) # 输出: list1 is list2 ? False (通常是 False,即使值相同)
print(f”list1 is list3 ? {list1 is list3}”) # 输出: list1 is list3 ? True (list3 引用了 list1 的对象)
身份不符 (is not)
print(f”list1 is not list2 ? {list1 is not list2}”) # 输出: list1 is not list2 ? True
print(f”list1 is not list3 ? {list1 is not list3}”) # 输出: list1 is not list3 ? False
检查对象是否为 None (常用场景)
检查变量是否为 None 时,强烈推荐使用 is None
或 is not None
,而不是 == None
或 != None
这是因为 None 是一个单例对象(Singleton),保证所有 None 都指向同一个内存地址
my_var = None
if my_var is None:
print(“my_var is None”) # 输出: my_var is None
another_var = 0 # 0 在布尔上下文中是 False
if another_var == None:
print(“another_var == None”) # 不会执行
if another_var is None:
print(“another_var is None”) # 不会执行
注意:某些对象(如用户自定义类的实例)可能重载了 == 运算符,但不会影响 is 的行为。
而 == 可能受到对象的 eq 方法影响。所以用 is None 是最准确和推荐的方式。
“`
总结: 身份运算符 is
和 is not
用于判断两个变量是否指向同一个对象。这与 ==
运算符比较对象的值不同。尤其是在判断一个变量是否为 None
时,应使用 is None
或 is not None
。理解可变和不可变类型在身份比较上的差异也很重要。
8. 运算符优先级 (Operator Precedence)
当一个表达式包含多个不同类型的运算符时,运算符优先级决定了它们的计算顺序。优先级高的运算符会先执行,优先级低的后执行。如果优先级相同,则根据结合性 (Associativity) 从左到右或从右到左计算。
记住完整的优先级表并不容易,也不是必须的。最重要的是理解基本的优先级规则,并在不确定时使用括号 ()
来明确指定计算顺序。括号内的表达式总是最先计算。
下面列出了一些常见运算符的优先级(从高到低,同一行的优先级相同):
()
: 括号 (最高优先级)**
: 幂运算+x
,-x
,~x
: 一元运算符 (正号, 负号, 按位取反)*
,/
,//
,%
: 乘法、除法、整除、取模+
,-
: 加法、减法<<
,>>
: 位移运算符&
: 按位与^
: 按位异或|
: 按位或- comparison,
in
,not in
,is
,is not
: 比较运算符,成员运算符,身份运算符 (通常优先级较低) not
: 逻辑非and
: 逻辑与or
: 逻辑或 (最低优先级)
示例演示优先级:
“`python
示例 1: 乘法优先级高于加法
print(f”2 + 3 * 4 = {2 + 3 * 4}”) # 结果是 14,因为先计算 3 * 4 = 12,再计算 2 + 12 = 14
使用括号改变优先级
print(f”(2 + 3) * 4 = {(2 + 3) * 4}”) # 结果是 20,因为先计算 (2 + 3) = 5,再计算 5 * 4 = 20
print(“-” * 20)
示例 2: 幂运算优先级高于乘法
print(f”2 * 3 ** 2 = {2 * 3 ** 2}”) # 结果是 18,因为先计算 3 ** 2 = 9,再计算 2 * 9 = 18
示例 3: 逻辑运算符的优先级
not > and > or
print(f”False and True or True = {False and True or True}”)
计算过程:
(False and True) or True
False or True
True
输出: False and True or True = True
print(f”False or True and True = {False or True and True}”)
计算过程:
False or (True and True)
False or True
True
输出: False or True and True = True
示例 4: 比较运算符与逻辑运算符
比较运算符优先级高于逻辑运算符
score = 85
print(f”score > 80 and score < 90 = {score > 80 and score < 90}”)
计算过程:
(score > 80) and (score < 90)
(85 > 80) and (85 < 90)
True and True
True
输出: score > 80 and score < 90 = True
使用链式比较更简洁,其优先级也低于逻辑运算符
print(f”80 < score < 90 = {80 < score < 90}”) # 等价于 (80 < score) and (score < 90)
计算过程:
(80 < score) and (score < 90)
(80 < 85) and (85 < 90)
True and True
True
输出: 80 < score < 90 = True
示例 5: 赋值运算符优先级最低
x = 5
y = 10
z = x + y * 2 # 先计算 y * 2,再计算 x + 结果,最后赋值给 z
print(f”x = {x}, y = {y}, z = x + y * 2 后, z = {z}”) # 输出: x = 5, y = 10, z = x + y * 2 后, z = 25
“`
总结: 了解运算符优先级可以帮助你正确预测表达式的计算结果。不确定时,使用括号是确保代码可读性和正确性的最佳实践。
9. 运算符结合性 (Operator Associativity)
当表达式中出现多个具有相同优先级的运算符时,结合性决定了它们的计算顺序。
- 左结合 (Left-associative): 大多数运算符是左结合的,例如
+
,-
,*
,/
,%
,//
。这意味着它们从左到右分组计算。- 例如:
a - b - c
被解析为(a - b) - c
- 例如:
a / b / c
被解析为(a / b) / c
- 例如:
- 右结合 (Right-associative): 幂运算符
**
是右结合的。- 例如:
a ** b ** c
被解析为a ** (b ** c)
- 例如:
- 非结合 (Non-associative): 比较运算符
==
,!=
,>
,<
,>=
,<=
是非结合的(尽管 Python 允许链式比较,这是一种特殊情况,不等同于简单的左右结合)。身份运算符is
,is not
也是非结合的。逻辑运算符and
,or
也不是简单的左右结合,因为它们有短路特性。
示例演示结合性:
“`python
左结合示例
print(f”10 – 5 – 2 = {10 – 5 – 2}”) # 相当于 (10 – 5) – 2 = 5 – 2 = 3
print(f”20 / 4 / 2 = {20 / 4 / 2}”) # 相当于 (20 / 4) / 2 = 5.0 / 2 = 2.5
右结合示例
print(f”2 ** 3 ** 2 = {2 ** 3 ** 2}”) # 相当于 2 ** (3 ** 2) = 2 ** 9 = 512
如果是左结合,结果将是 (2 ** 3) ** 2 = 8 ** 2 = 64,这与实际结果不同
print(f”(2 ** 3) ** 2 = {(2 ** 3) ** 2}”) # 通过括号强制左结合
链式比较的结合性 (特殊情况)
1 < x < 10 是特殊的链式比较,它等价于 (1 < x) and (x < 10)
而不是简单的 1 < (x < 10) 或 (1 < x) < 10
1 < x < 10 是一种语法糖,其行为并非简单的左结合或右结合
“`
总结: 虽然不像优先级那样重要,但了解结合性可以帮助理解在没有括号的情况下,同等优先级的运算符如何被分组计算。幂运算符 **
的右结合性是一个需要特别记住的例外。链式比较是 Python 独特的语法特性,应理解其等价形式。
结论
运算符是 Python 语言的核心组成部分,它们赋予了程序处理数据和执行逻辑的能力。本文详细介绍了 Python 中常用的算术运算符、比较运算符、赋值运算符、逻辑运算符、位运算符、成员运算符和身份运算符,并通过丰富的代码示例演示了它们的用法和特性。
- 算术运算符 负责基本的数学计算。
- 比较运算符 用于判断值之间的关系,结果为布尔值。
- 赋值运算符 用于给变量赋值,复合赋值运算符简化了常见操作。
- 逻辑运算符 用于组合和操作布尔表达式,是控制程序流程的关键。
- 位运算符 操作整数的二进制位,在特定领域有用。
- 成员运算符 检查元素是否存在于序列或集合中。
- 身份运算符 判断两个变量是否引用同一个对象。
理解运算符的优先级和结合性可以帮助你正确解析复杂的表达式。
掌握这些基本运算符是编写任何 Python 程序的基础。建议你亲自运行文中的示例代码,尝试修改数值和表达式,观察输出结果,加深理解。在实际编程中,你会频繁地使用这些运算符来构建更复杂的功能。不断练习,你将能够熟练地运用它们,编写出高效、清晰的 Python 代码。
继续学习更高级的 Python 特性,如控制流语句(if, for, while)、函数、数据结构等,你会发现运算符是构建这些高级特性的基石。祝你在 Python 的学习旅程中一切顺利!