Python运算符详解

运算符是Python编程中用于执行各种操作的特殊符号。Python提供了丰富的运算符,用于处理不同类型的数据和执行各种运算。本文将详细介绍Python中的各种运算符类型、语法规则和使用方法。

一、运算符概述

1. 什么是运算符?

运算符是一种特殊的符号,用于表示数据的运算、赋值和比较等操作。例如,+用于加法运算,=用于赋值操作,>用于比较大小等。

2. 运算符的分类

Python中的运算符可以分为以下几类:

运算符类型 描述 示例
算术运算符 用于数学运算 +, -, *, /, //, %, **
比较运算符 用于比较两个值 ==, !=, >, <, >=, <=
赋值运算符 用于赋值操作 =, +=, -=, *=, /=, //=, %=, **=
逻辑运算符 用于逻辑运算 and, or, not
成员运算符 检查元素是否在序列中 in, not in
身份运算符 检查两个对象是否引用同一个内存地址 is, is not
位运算符 用于二进制位运算 &, `

3. 运算符优先级

当一个表达式包含多个运算符时,Python会按照一定的优先级顺序执行运算。优先级高的运算符先执行,优先级低的运算符后执行。如果运算符的优先级相同,则按照结合性规则执行。

二、算术运算符

算术运算符用于执行基本的数学运算。

运算符 描述 示例
+ 加法 a + b
- 减法 a - b
* 乘法 a * b
/ 除法(结果为浮点数) a / b
// 整数除法(向下取整) a // b
% 取余(模运算) a % b
** 幂运算(a的b次方) a ** b

示例代码

# 算术运算符示例
a = 10
b = 3

print(f"a + b = {a + b}")  # 13
print(f"a - b = {a - b}")  # 7
print(f"a * b = {a * b}")  # 30
print(f"a / b = {a / b}")  # 3.3333333333333335
print(f"a // b = {a // b}")  # 3
print(f"a % b = {a % b}")  # 1
print(f"a ** b = {a ** b}")  # 1000

# 浮点数运算
c = 3.14
d = 2.0
print(f"c + d = {c + d}")  # 5.14
print(f"c * d = {c * d}")  # 6.28

# 负数运算
e = -5
f = 3
print(f"e + f = {e + f}")  # -2
print(f"e * f = {e * f}")  # -15

注意事项

  • 除法运算符/总是返回浮点数,即使两个操作数都是整数
  • 整数除法//会向下取整,对于负数也会向下取整(如-10 // 3结果为-4
  • 幂运算符**的优先级高于一元运算符(如-3**2结果为-9,而(-3)**2结果为9

三、比较运算符

比较运算符用于比较两个值的大小或相等性,返回布尔值TrueFalse

运算符 描述 示例
== 等于 a == b
!= 不等于 a != b
> 大于 a > b
< 小于 a < b
>= 大于等于 a >= b
<= 小于等于 a <= b

示例代码

# 比较运算符示例
a = 10
b = 3

print(f"a == b: {a == b}")  # False
print(f"a != b: {a != b}")  # True
print(f"a > b: {a > b}")  # True
print(f"a < b: {a < b}")  # False
print(f"a >= b: {a >= b}")  # True
print(f"a <= b: {a <= b}")  # False

# 字符串比较
str1 = "apple"
str2 = "banana"
print(f"str1 == str2: {str1 == str2}")  # False
print(f"str1 < str2: {str1 < str2}")  # True(按字典序比较)

# 列表比较
list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = [1, 2, 4]
print(f"list1 == list2: {list1 == list2}")  # True
print(f"list1 < list3: {list1 < list3}")  # True

注意事项

  • 比较运算符可以比较相同类型的任何值
  • 字符串比较是按字典序进行的(Unicode码点)
  • 列表和元组比较是按元素逐个比较的
  • 比较运算可以链式使用(如1 < 2 < 3结果为True

四、赋值运算符

赋值运算符用于将值赋给变量。Python提供了基本赋值运算符和复合赋值运算符。

1. 基本赋值运算符

运算符 描述 示例
= 赋值 a = b

2. 复合赋值运算符

运算符 描述 示例 等价于
+= 加法赋值 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
^= 位异或赋值 a ^= b a = a ^ b
<<= 左移赋值 a <<= b a = a << b
>>= 右移赋值 a >>= b a = a >> b

示例代码

# 赋值运算符示例
x = 10  # 基本赋值
print(f"x = {x}")  # 10

x += 5  # 加法赋值(x = x + 5)
print(f"x += 5: {x}")  # 15

x -= 3  # 减法赋值(x = x - 3)
print(f"x -= 3: {x}")  # 12

x *= 2  # 乘法赋值(x = x * 2)
print(f"x *= 2: {x}")  # 24

x /= 4  # 除法赋值(x = x / 4)
print(f"x /= 4: {x}")  # 6.0

x //= 2  # 整数除法赋值(x = x // 2)
print(f"x //= 2: {x}")  # 3.0

x **= 3  # 幂赋值(x = x ** 3)
print(f"x **= 3: {x}")  # 27.0

# 位运算赋值
y = 5  # 二进制:0101
y <<= 1  # 左移赋值(y = y << 1)
print(f"y <<= 1: {y}")  # 10(二进制:1010)

注意事项

  • 复合赋值运算符可以简化代码,提高可读性
  • 赋值运算的优先级较低,通常在其他运算完成后执行

五、逻辑运算符

逻辑运算符用于执行逻辑运算,通常与布尔值一起使用,返回布尔值TrueFalse

运算符 描述 示例
and 逻辑与(都为真才为真) a and b
or 逻辑或(有一个为真就为真) a or b
not 逻辑非(取反) not a

示例代码

# 逻辑运算符示例
x = True
y = False

print(f"x and y: {x and y}")  # False
print(f"x or y: {x or y}")  # True
print(f"not x: {not x}")  # False

# 短路求值
a = 0
b = 5

# and运算符:如果第一个操作数为False,第二个操作数不会被计算
result1 = a and (b / a)  # 不会引发ZeroDivisionError
print(f"result1: {result1}")  # 0

# or运算符:如果第一个操作数为True,第二个操作数不会被计算
result2 = b or (b / a)  # 不会引发ZeroDivisionError
print(f"result2: {result2}")  # 5

# 非布尔值的逻辑运算
# 在Python中,任何值都可以被视为布尔值
# 0、空字符串、空列表等被视为False,其他值被视为True
print(f"not 0: {not 0}")  # True
print(f"not '': {not ''}")  # True
print(f"not [1, 2, 3]: {not [1, 2, 3]}")  # False
print(f"'a' and 'b': {'a' and 'b'}")  # 'b'(返回最后一个真值)
print(f"'' or 'b': {'' or 'b'}")  # 'b'(返回第一个真值)

注意事项

  • Python使用短路求值(short-circuit evaluation):
    • and:如果第一个操作数为False,不计算第二个操作数
    • or:如果第一个操作数为True,不计算第二个操作数
  • 逻辑运算符可以用于非布尔值,此时返回的是实际的值,而不是布尔值

六、成员运算符

成员运算符用于检查一个值是否属于某个序列(如列表、元组、字符串、集合、字典)。

运算符 描述 示例
in 如果在序列中找到值返回True value in sequence
not in 如果在序列中找不到值返回True value not in sequence

示例代码

# 成员运算符示例
# 列表
fruits = ["apple", "banana", "orange"]
print(f"'apple' in fruits: {'apple' in fruits}")  # True
print(f"'grape' not in fruits: {'grape' not in fruits}")  # True

# 字符串
text = "Hello, World!"
print(f"'Hello' in text: {'Hello' in text}")  # True
print(f"'Python' not in text: {'Python' not in text}")  # True

# 元组
numbers = (1, 2, 3, 4, 5)
print(f"3 in numbers: {3 in numbers}")  # True
print(f"6 not in numbers: {6 not in numbers}")  # True

# 集合
colors = {"red", "green", "blue"}
print(f"'red' in colors: {'red' in colors}")  # True

# 字典(检查键是否存在)
person = {"name": "张荣殿", "age": 30, "city": "北京"}
print(f"'name' in person: {'name' in person}")  # True
print(f"'张荣殿' in person: {'张荣殿' in person}")  # False(字典默认检查键)
print(f"'张荣殿' in person.values(): {'张荣殿' in person.values()}")  # True(检查值)

注意事项

  • 对于字典,in运算符检查的是键,而不是值
  • 成员运算符在字符串中检查的是子串,而不是单个字符
  • 集合和字典的成员检查速度比列表和元组快(使用哈希表)

七、身份运算符

身份运算符用于检查两个对象是否引用同一个内存地址(即是否是同一个对象)。

运算符 描述 示例
is 如果两个对象引用同一个内存地址返回True a is b
is not 如果两个对象引用不同的内存地址返回True a is not b

示例代码

# 身份运算符示例
# 相同值的整数(小整数缓存)
x = 10
y = 10
print(f"x is y: {x is y}")  # True(小整数缓存机制)
print(f"x == y: {x == y}")  # True

# 较大的整数(超出小整数缓存范围)
a = 257
b = 257
print(f"a is b: {a is b}")  # False
print(f"a == b: {a == b}")  # True

# 列表
tolist1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = list1
print(f"list1 is list2: {list1 is list2}")  # False(不同的对象)
print(f"list1 == list2: {list1 == list2}")  # True(值相同)
print(f"list1 is list3: {list1 is list3}")  # True(同一个对象)

# None检查
c = None
print(f"c is None: {c is None}")  # True
print(f"c is not None: {c is not None}")  # False

注意事项

  • is==的区别:
    • is检查的是身份(内存地址)
    • ==检查的是值是否相等
  • Python对小整数(-5到256)和短字符串使用缓存机制,所以相同值的小整数可能是同一个对象
  • 对于None的检查,推荐使用is None而不是== None

八、位运算符

位运算符用于对整数的二进制位进行操作。

运算符 描述 示例
& 按位与 a & b
` ` 按位或
^ 按位异或 a ^ b
~ 按位取反 ~a
<< 左移 a << b
>> 右移 a >> b

示例代码

# 位运算符示例
# 二进制表示:
# 5 = 0101
# 3 = 0011
a = 5
b = 3

print(f"a = {a} (二进制: {bin(a)})")  # a = 5 (二进制: 0b101)
print(f"b = {b} (二进制: {bin(b)})")  # b = 3 (二进制: 0b11)

# 按位与(都为1时结果为1)
print(f"a & b = {a & b} (二进制: {bin(a & b)})")  # 1 (二进制: 0b1)

# 按位或(有一个为1时结果为1)
print(f"a | b = {a | b} (二进制: {bin(a | b)})")  # 7 (二进制: 0b111)

# 按位异或(不同时结果为1)
print(f"a ^ b = {a ^ b} (二进制: {bin(a ^ b)})")  # 6 (二进制: 0b110)

# 按位取反(每一位都取反,包括符号位)
print(f"~a = {~a} (二进制: {bin(~a)})")  # -6 (二进制: -0b110)

# 左移(左移n位相当于乘以2的n次方)
print(f"a << 1 = {a << 1} (二进制: {bin(a << 1)})")  # 10 (二进制: 0b1010)
print(f"a << 2 = {a << 2} (二进制: {bin(a << 2)})")  # 20 (二进制: 0b10100)

# 右移(右移n位相当于除以2的n次方,向下取整)
print(f"a >> 1 = {a >> 1} (二进制: {bin(a >> 1)})")  # 2 (二进制: 0b10)
print(f"a >> 2 = {a >> 2} (二进制: {bin(a >> 2)})")  # 1 (二进制: 0b1)

# 负数的位运算(使用补码表示)
c = -5
print(f"c = {c} (二进制: {bin(c)})")  # c = -5 (二进制: -0b101)
print(f"c >> 1 = {c >> 1} (二进制: {bin(c >> 1)})")  # -3 (二进制: -0b11)

注意事项

  • 位运算符只适用于整数类型
  • 按位取反运算符~会改变符号位,结果与原数的关系是:~x = -x - 1
  • 左移和右移运算符的结果取决于操作数的符号:
    • 正数:右移时高位补0
    • 负数:右移时高位补1(保持负数符号)

九、运算符优先级

运算符优先级决定了表达式中运算的执行顺序。优先级高的运算符先执行,优先级低的运算符后执行。

优先级 运算符 描述
1 () 括号
2 ** 幂运算
3 ~ 按位取反
4 *, /, //, % 乘、除、整数除法、取余
5 +, - 加、减
6 <<, >> 左移、右移
7 & 按位与
8 ^ 按位异或
9 ` `
10 ==, !=, >, <, >=, <=, is, is not, in, not in 比较运算符和身份/成员运算符
11 not 逻辑非
12 and 逻辑与
13 or 逻辑或
14 =, +=, -=, *=, /=, //=, %=, **=, &=, ` =, ^=, <<=, >>=`

示例代码

# 运算符优先级示例
# 1. 括号优先级最高
result1 = (2 + 3) * 4  # 20
print(f"(2 + 3) * 4 = {result1}")

# 2. 幂运算优先级高于乘除
result2 = 2 ** 3 * 4  # 32(先算2**3=8,再算8*4=32)
print(f"2 ** 3 * 4 = {result2}")

# 3. 乘除优先级高于加减
result3 = 2 + 3 * 4  # 14(先算3*4=12,再算2+12=14)
print(f"2 + 3 * 4 = {result3}")

# 4. 比较运算符优先级高于逻辑运算符
result4 = 1 < 2 and 3 > 4  # False(先算1<2=True,3>4=False,再算True and False=False)
print(f"1 < 2 and 3 > 4 = {result4}")

# 5. 逻辑非优先级高于逻辑与和逻辑或
result5 = not 1 < 2 or 3 > 4  # False(先算not 1<2=False,再算False or 3>4=False)
print(f"not 1 < 2 or 3 > 4 = {result5}")

注意事项

  • 使用括号可以改变运算顺序,提高代码的可读性
  • 当表达式复杂时,建议使用括号明确指定运算顺序

十、运算符结合性

当运算符的优先级相同时,运算的执行顺序由结合性决定。

运算符 结合性
() 从左到右
** 从右到左
一元运算符(~, not 从右到左
二元运算符(+, -, *, /, //, %, &, ` , ^, <<, >>, ==, !=, >, <, >=, <=, is, is not, in, not in, and, or`)
赋值运算符 从右到左

示例代码

# 运算符结合性示例
# 1. 幂运算(从右到左)
result1 = 2 ** 3 ** 2  # 2^(3^2) = 2^9 = 512
print(f"2 ** 3 ** 2 = {result1}")

# 2. 赋值运算符(从右到左)
a = b = c = 10  # 等价于 a = (b = (c = 10))
print(f"a = {a}, b = {b}, c = {c}")  # a = 10, b = 10, c = 10

# 3. 加减乘除(从左到右)
result2 = 10 - 5 + 3  # (10 - 5) + 3 = 8
print(f"10 - 5 + 3 = {result2}")

# 4. 比较运算符(从左到右)
result3 = 1 < 2 < 3  # (1 < 2) and (2 < 3) = True
print(f"1 < 2 < 3 = {result3}")

十一、特殊运算符

除了上述基本运算符外,Python还提供了一些特殊的运算符:

1. 三元运算符(条件表达式)

三元运算符用于根据条件选择不同的值,语法为:值1 if 条件 else 值2

# 三元运算符示例
age = 20
status = "成年人" if age >= 18 else "未成年人"
print(f"年龄 {age} 岁,是 {status}")  # 年龄 20 岁,是 成年人

# 复杂的三元表达式
x = 10
y = 20
max_value = x if x > y else y
print(f"最大值:{max_value}")  # 最大值:20

2. 解包运算符

解包运算符用于将序列或字典解包为单独的值:

  • *:用于列表、元组等序列
  • **:用于字典
# 解包运算符示例
# 列表解包
a, b, *rest = [1, 2, 3, 4, 5]
print(f"a = {a}, b = {b}, rest = {rest}")  # a = 1, b = 2, rest = [3, 4, 5]

# 元组解包
x, y, z = (10, 20, 30)
print(f"x = {x}, y = {y}, z = {z}")  # x = 10, y = 20, z = 30

# 函数参数解包
def add(a, b, c):
    return a + b + c

numbers = [1, 2, 3]
result = add(*numbers)  # 等价于 add(1, 2, 3)
print(f"add(*numbers) = {result}")  # 6

# 字典解包
def person_info(name, age, city):
    print(f"姓名:{name}, 年龄:{age}, 城市:{city}")

info = {"name": "张荣殿", "age": 30, "city": "北京"}
person_info(**info)  # 等价于 person_info(name="张荣殿", age=30, city="北京")

3. 海象运算符(Python 3.8+)

海象运算符(:=)用于在表达式中赋值,语法为:变量 := 表达式

# 海象运算符示例(需要Python 3.8+)

# 在条件语句中使用
text = "Hello, World!"
if (length := len(text)) > 10:
    print(f"文本长度为 {length},超过10个字符")  # 文本长度为 13,超过10个字符

# 在循环中使用
import random

while (number := random.randint(1, 10)) != 5:
    print(f"生成的数字:{number}")
print(f"最终生成的数字:{number}")

# 在列表推导式中使用
data = ["apple", "banana", "orange", "grape"]
lengths = [len(item) for item in data if (len(item) > 5)]
print(f"长度大于5的水果名长度:{lengths}")  # [6, 6, 5](注意:原代码中的条件应该是 >4 才会包含 grape)

十二、运算符的最佳实践

1. 使用括号提高可读性

当表达式复杂时,使用括号明确指定运算顺序,提高代码的可读性。

# 不好的写法
result = 2 + 3 * 4 ** 2 - 1

# 好的写法
result = 2 + (3 * (4 ** 2)) - 1

2. 避免过度使用复杂表达式

复杂的表达式会降低代码的可读性,建议将其分解为多个简单的表达式。

# 不好的写法
result = (x > 5 and y < 10) or (x < 0 and y > 20) and (z != 0)

# 好的写法
condition1 = x > 5 and y < 10
condition2 = x < 0 and y > 20
condition3 = z != 0
result = (condition1 or condition2) and condition3

3. 使用比较运算符的链式写法

Python支持比较运算符的链式写法,使代码更简洁。

# 不好的写法
if x >= 0 and x <= 100:
    pass

# 好的写法
if 0 <= x <= 100:
    pass

4. 使用身份运算符检查None

对于None的检查,推荐使用is None而不是== None

# 不好的写法
if x == None:
    pass

# 好的写法
if x is None:
    pass

5. 利用短路求值优化代码

使用短路求值可以避免不必要的计算,提高代码效率。

# 不好的写法
def is_valid(x):
    return x is not None and len(x) > 0

# 好的写法(已经是短路求值)
def is_valid(x):
    return x is not None and len(x) > 0  # 如果x是None,不会执行len(x)

# 另一个例子:避免除零错误
def safe_divide(a, b):
    return b != 0 and (a / b)  # 如果b是0,不执行除法

十三、总结

Python提供了丰富的运算符,用于执行各种操作:

  1. 算术运算符:用于基本数学运算
  2. 比较运算符:用于比较值的大小和相等性
  3. 赋值运算符:用于给变量赋值
  4. 逻辑运算符:用于执行逻辑运算
  5. 成员运算符:用于检查值是否属于序列
  6. 身份运算符:用于检查对象的身份
  7. 位运算符:用于操作二进制位
  8. 特殊运算符:三元运算符、解包运算符、海象运算符等

理解运算符的优先级和结合性对于编写正确的表达式非常重要。在编写代码时,应该遵循最佳实践,使用括号提高可读性,避免过度复杂的表达式,并利用Python的特性(如短路求值、链式比较)简化代码。


发布网站:荣殿教程(zhangrongdian.com)

作者:张荣殿