当我们编写Python程序时,实际上是在构建各种各样的表达式来描述计算过程。表达式就像是数学公式一样,它告诉计算机“我想要计算什么”以及“怎样计算”。 无论是简单的数学运算,还是复杂的逻辑判断,都离不开表达式的参与。在这一节课中,我们将深入了解Python中表达式的各种形式,学习如何组合不同的元素来创建功能强大的程序。

表达式是Python程序的基本构成单位,它由操作数和操作符组成,就像数学表达式一样。最简单的表达式可能只是一个数字,比如42,或者一个变量名,比如score。
更复杂的表达式则通过运算符将多个操作数连接起来,比如price * quantity + shipping_cost。
当Python遇到一个表达式时,它会按照特定的规则对其进行求值,最终得到一个结果。这个过程就像解数学题一样,先识别出表达式中的各个部分,然后按照运算优先级和结合性规则逐步计算,最终得到答案。
理解表达式求值的过程对于编写正确的程序至关重要。Python解释器会严格按照语言规范定义的规则来计算表达式,不会有任何模糊性或随意性。 这意味着相同的表达式在任何时候、任何环境下都会产生相同的结果,这种确定性是程序可靠性的基础。
让我们通过一个简单的例子来感受表达式的作用:
|# 简单的表达式示例 price = 29.99 quantity = 3 tax_rate = 0.08 # 复合表达式计算总价 total = price * quantity * (1 + tax_rate) print(f"商品总价:{total:.2f}元")
在这个例子中,price * quantity * (1 + tax_rate)是一个包含多个运算符的复合表达式。Python会先计算括号内的1 + tax_rate,然后从左到右进行乘法运算,最终得到总价。
算术表达式是编程中最常见也是最基础的表达式类型。Python支持所有基本的数学运算,包括加法、减法、乘法、除法,以及一些特殊的运算如整数除法、取余和幂运算。
Python的算术运算符与数学中的运算符号基本相同,但有一些特殊之处需要注意。加法运算符+不仅可以用于数字相加,还可以用于字符串连接。
减法运算符-可以作为二元运算符用于两个数相减,也可以作为一元运算符表示负数。
|# 基本算术运算 a = 15 b = 4 print(f"加法:{a} + {b} = {a + b}") print(f"减法:{a} - {b} = {a - b}") print(f"乘法:{a} * {b} = {a * b}") print(f"除法:{a} / {b} = {a / b}") print(f"整数除法:{a} // {b} = {a // b}") print(f"取余:{a} % {b} = {a % b}") print(f"幂运算:{a} ** {b} = {a ** b}")
整数除法运算符//会向下取整,即使是负数也是如此。这个特性在某些计算中很有用,比如计算页数或分组数量。
就像数学运算一样,Python的算术运算符有着明确的优先级顺序。幂运算具有最高的优先级,其次是一元的正负号,然后是乘法、除法、整数除法和取余,最后是加法和减法。 相同优先级的运算符按照从左到右的顺序进行计算,但幂运算是个例外,它是从右到左结合的。
|# 运算符优先级示例 result1 = 2 + 3 * 4 # 结果是14,不是20 result2 = 2 ** 3 ** 2 # 结果是512(2的9次方),不是64 print(f"2 + 3 * 4 = {result1}") print(f"2 ** 3 ** 2 = {result2}") # 使用括号改变运算顺序 result3 = (2 + 3) * 4 # 结果是20 result4 = (2 ** 3) ** 2 # 结果是64 print(f"(2 + 3) * 4 = {result3}") print(f"(2 ** 3) ** 2 = {result4}")
当表达式变得复杂时,明智的做法是使用括号来明确表达你的意图,即使在不必要的情况下也是如此。这样可以让代码更容易理解,减少因为优先级理解错误而导致的bug。
在算术表达式中,当不同类型的数值参与运算时,Python会自动进行类型转换以确保运算的正确性。整数与浮点数运算时,结果总是浮点数。这种设计避免了精度损失,确保了计算结果的准确性。
|# 类型自动转换 integer_num = 10 float_num = 3.5 result = integer_num + float_num print(f"整数 + 浮点数 = {result},类型:{type(result)}") # 除法运算总是返回浮点数 division_result = 20 / 4 print(f"20 / 4 = {division_result},类型:{type(division_result)}") # 整数除法返回整数(如果操作数都是整数) floor_division_result = 20 // 3 print(f"20 // 3 = {floor_division_result},类型:{type(floor_division_result)}")
Python能够处理一些特殊的数值情况,包括无穷大和非数值(NaN)。这些特殊值在科学计算和数据处理中经常遇到。
|import math # 无穷大 positive_infinity = float('inf') negative_infinity = float('-inf') print(f"正无穷:{positive_infinity}") print(f"负无穷:{negative_infinity}") print(f"1 / 0 的结果(当用浮点数时):{1.0 / 0}") # 会产生警告但不会错误 # 非数值 (Not a Number) not_a_number = float('nan') print(f"NaN:{not_a_number}") print(f"0 / 0 的结果:{0.0 / 0}") # 会产生警告
需要注意的是,当涉及整数的除零操作时,Python会抛出ZeroDivisionError异常,而不是返回无穷大。
比较表达式用于判断两个值之间的关系,是程序中决策制定的基础。Python提供了丰富的比较运算符,能够处理各种数据类型之间的比较。
最直观的比较是数值之间的大小比较。Python支持所有标准的比较运算符,包括等于、不等于、大于、小于、大于等于和小于等于。
|# 数值比较示例 score = 85 passing_grade = 60 print(f"是否及格:{score >= passing_grade}") print(f"是否满分:{score == 100}") print(f"是否需要补考:{score < passing_grade}") # 可以进行链式比较 age = 25 print(f"是否成年且未满退休年龄:{18 <= age < 65}") # 浮点数比较需要注意精度问题 result = 0.1 + 0.2 print(f"0.1 + 0.2 是否等于 0.3:{result == 0.3}") print(f"实际结果:{result}")
链式比较是Python的一个独特特性,它允许我们用更自然的方式表达数学中的区间概念。表达式a < b < c等价于a < b and b < c,但更加简洁易读。
字符串的比较基于字典序,即按照字符的Unicode码值进行比较。这种比较方式在排序和搜索中很有用。
|# 字符串比较 name1 = "Alice" name2 = "Bob" name3 = "alice" print(f"字典序比较:{'Alice' < 'Bob'}") print(f"大小写敏感:{'Alice' == 'alice'}") print(f"长度对比较的影响:{'cat' < 'category'}") # 字符串方法在比较中的应用 print(f"忽略大小写比较:{name1.lower() == name3.lower()}")
Python还允许对列表、元组等容器类型进行比较。比较是按照元素的顺序逐个进行的,类似于字符串的字典序比较。
|# 列表比较 list1 = [1, 2, 3] list2 = [1, 2, 4] list3 = [1, 2] print(f"列表按字典序比较:{list1 < list2}") print(f"长度对比较的影响:{list3 < list1}") # 元组比较 tuple1 = (1, 2, 3) tuple2 = (1, 2, 3) print(f"元组相等比较:{tuple1 == tuple2}")
除了值的比较,Python还提供了身份比较和成员测试的操作符。is运算符检查两个变量是否指向同一个对象,而in运算符检查一个值是否存在于容器中。
|# 身份比较 a = [1, 2, 3] b = [1, 2, 3] c = a print(f"值相等但不是同一对象:{a == b and a is not b}") print(f"指向同一对象:{a is c}") # 成员测试 fruits = ['苹果', '香蕉', '橙子'] print(f"苹果在水果列表中:{'苹果' in fruits}") print(f"葡萄不在水果列表中:{'葡萄' not in fruits}") # 字符串成员测试 text = "Python编程很有趣" print(f"是否包含'编程':{'编程' in text}")
逻辑表达式通过逻辑运算符将多个条件组合起来,形成更复杂的判断条件。Python提供了三个基本的逻辑运算符:and、or和not。

and运算符只有在所有条件都为真时才返回真值。这种运算具有短路特性,即如果第一个条件为假,Python就不会计算后续的条件。
|# 逻辑与运算示例 age = 20 income = 5000 # 申请信用卡的条件:年龄大于18且收入大于3000 can_apply_card = age > 18 and income > 3000 print(f"是否可以申请信用卡:{can_apply_card}") # 短路特性演示 def expensive_check(): print("执行了昂贵的检查操作") return True # 由于第一个条件为假,不会执行expensive_check函数 result = False and expensive_check() print(f"短路结果:{result}")
注意在上述例子中我们定义了一个简单的expensive_check函数,我们后续会介绍如何定义和使用函数,你暂时可以忽略它。
or运算符只要有一个条件为真就返回真值。它同样具有短路特性,如果第一个条件为真,就不会计算后续条件。
|# 逻辑或运算示例 weekend = True holiday = False # 可以休息的条件:周末或者假期 can_rest = weekend or holiday print(f"今天可以休息:{can_rest}") # 设置默认值的常见用法 user_name = "" display_name = user_name or "匿名用户" print(f"显示名称:{display_name}") # 多条件的或运算 score = 75 is_excellent = score >= 90 or score >= 80 and has_bonus_points
not运算符将真值转换为假值,将假值转换为真值。它常用于条件的反转和布尔值的切换。
|# 逻辑非运算示例 is_logged_in = False needs_login = not is_logged_in print(f"需要登录:{needs_login}") # 检查空容器 shopping_cart = [] cart_is_empty = not shopping_cart print(f"购物车为空:{cart_is_empty}") # 复杂条件中的非运算 password = "12345" is_weak_password = not (len(password) >= 8 and any(c.isalpha() for c in password)) print(f"密码强度不够:{is_weak_password}")
在实际编程中,我们经常需要构建包含多个逻辑运算符的复杂表达式。理解运算符的优先级和合理使用括号对于编写正确的逻辑表达式至关重要。
|# 复杂逻辑表达式示例 age = 25 has_license = True has_car = False emergency = True # 可以驾驶的条件 can_drive = (age >= 18 and has_license) and (has_car or emergency) print(f"可以驾驶:{can_drive}") # 学生折扣条件 is_student = True age = 20 has_student_id = True gets_discount = is_student and (age <= 25 or has_student_id) print(f"享受学生折扣:{gets_discount}")
在Python中,逻辑运算符and和or的返回值并不总是True或False,而是参与运算的实际值。and返回第一个假值或最后一个真值,or返回第一个真值或最后一个假值。这个特性在设置默认值等场景中很有用。
字符串表达式不仅包括字符串字面量,还包括各种字符串操作和方法调用。Python为字符串处理提供了丰富的操作符和内置方法。
字符串可以通过+运算符进行连接,通过*运算符进行重复。这些操作在构建动态字符串时非常有用。
|# 字符串连接 first_name = "张" last_name = "小明" full_name = first_name + last_name print(f"完整姓名:{full_name}") # 字符串重复 separator = "-" * 20 print(separator) print("重要通知") print(separator) # 连接多个字符串 greeting = "您好," + full_name + "先生" print(greeting) # 更复杂的字符串构建 border = "=" * 30 title = "欢迎使用Python" formatted_title = border + "\n" + title.center(30) + "\n" + border print(formatted_title)
现代Python推荐使用f-字符串进行字符串格式化,它不仅语法简洁,而且性能优秀。f-字符串内部可以包含任意的Python表达式。
|# f-字符串格式化 name = "小王" age = 28 salary = 8500.5 # 基本格式化 intro = f"我叫{name},今年{age}岁" print(intro) # 表达式计算 next_year_age = f"明年我就{age + 1}岁了" print(next_year_age) # 数字格式化 formatted_salary = f"我的月薪是{salary:,.2f}元" print(formatted_salary) # 条件表达式在f-字符串中的使用 status = f"{name}{'已成年' if age >= 18 else '未成年'}" print(status)
字符串对象提供了大量的内置方法,这些方法调用本身也是表达式,可以链式调用或组合使用。
|# 字符串方法链式调用 user_input = " Hello, World! " processed = user_input.strip().lower().replace("world", "python") print(f"处理后的字符串:'{processed}'") # 字符串测试方法 email = "user@example.com" is_valid_format = "@" in email and "." in email.split("@")[1] print(f"邮箱格式正确:{is_valid_format}") # 字符串分割和组合 sentence = "Python是一门优秀的编程语言" words = sentence.split("是") reconstructed = "确实是".join(words) print(f"重构后的句子:{reconstructed}") # 条件检查方法 password = "MyPassword123" is_strong = (len(password) >= 8 and any(c.isupper() for c in password) and any(c.islower() for c in password) and any(c.isdigit() for c in password)) print(f"密码强度足够:{is_strong}")
字符串切片是一种强大的子字符串提取方式,它返回原字符串的一个片段。
|# 字符串切片 text = "Python编程很有趣" # 基本切片 first_part = text[:6] # 前6个字符 last_part = text[6:] # 从第7个字符到末尾 middle = text[2:8] # 第3到第8个字符 print(f"前半部分:{first_part}") print(f"后半部分:{last_part}") print(f"中间部分:{middle}") # 带步长的切片 reversed_text = text[::-1] # 反转字符串 every_second = text[::2] # 每隔一个字符取一个 print(f"反转后:{reversed_text}") print(f"每隔一个字符:{every_second}") # 组合切片操作 filename = "document.pdf" name_part = filename[:filename.rfind('.')] extension = filename[filename.rfind('.') + 1:] print(f"文件名:{name_part},扩展名:{extension}")
容器表达式涉及列表、元组、字典等容器类型的操作。这些表达式在数据处理和集合操作中发挥着重要作用。
列表表达式包括列表的创建、元素访问、切片操作等。Python的索引系统既支持正向索引也支持负向索引。
|# 列表创建和访问 scores = [85, 92, 78, 96, 88] student_names = ["小明", "小红", "小刚", "小丽", "小华"] # 索引访问表达式 best_score = scores[0] if scores else 0 last_student = student_names[-1] print(f"最高分:{best_score}") print(f"最后一个学生:{last_student}") # 条件索引访问 index = 2 safe_access = scores[index] if 0 <= index < len(scores) else "无效索引" print(f"安全访问结果:{safe_access}") # 列表切片表达式 top_three = scores[:3] bottom_two = scores[-2:] middle_section = scores[1:-1] print(f"前三名分数:{top_three}") print(f"后两名分数:{bottom_two}") print(f"中间部分:{middle_section}")
列表的方法调用虽然主要用于修改列表,但某些方法也会返回值,可以作为表达式的一部分。
|# 列表方法表达式 numbers = [1, 2, 3, 2, 4, 2, 5] # 查找方法 first_occurrence = numbers.index(2) count_of_twos = numbers.count(2) print(f"数字2第一次出现的位置:{first_occurrence}") print(f"数字2出现的次数:{count_of_twos}") # 列表复制和扩展 original = [1, 2, 3] doubled = original * 2 extended = original + [4, 5, 6] print(f"重复列表:{doubled}") print(f"扩展列表:{extended}") # 列表推导式表达式 squares = [x**2 for x in range(1, 6)] even_squares = [x**2 for x in range(1, 11) if x % 2 == 0] print(f"平方数列表:{squares}") print(f"偶数的平方:{even_squares}")
容器类型支持成员测试和比较操作,这些操作在数据筛选和条件判断中非常有用。
|# 成员测试表达式 fruits = ["苹果", "香蕉", "橙子", "葡萄"] vegetables = ["白菜", "萝卜", "西红柿"] has_apple = "苹果" in fruits has_tomato = "西红柿" in vegetables has_both = "苹果" in fruits and "萝卜" in vegetables print(f"有苹果:{has_apple}") print(f"有西红柿:{has_tomato}") print(f"既有苹果又有萝卜:{has_both}") # 列表比较表达式 list1 = [1, 2, 3] list2 = [1, 2, 3] list3 = [1, 2, 4] are_equal = list1 == list2 is_lexicographically_smaller = list1 < list3 print(f"列表相等:{are_equal}") print(f"字典序比较:{is_lexicographically_smaller}") # 嵌套容器的成员测试 matrix = [[1, 2], [3, 4], [5, 6]] has_row = [3, 4] in matrix has_element = any(3 in row for row in matrix) print(f"包含行[3, 4]:{has_row}") print(f"包含元素3:{has_element}")
函数调用本身就是一种表达式,它可以接受参数并返回值。Python中的函数调用表达式可以嵌套使用,形成复杂的计算过程。
Python提供了丰富的内置函数,这些函数调用是表达式运算的重要组成部分。
|# 数学函数调用 numbers = [3, 1, 4, 1, 5, 9, 2, 6] maximum = max(numbers) minimum = min(numbers) total = sum(numbers) count = len(numbers) average = sum(numbers) / len(numbers) print(f"最大值:{maximum}") print(f"最小值:{minimum}") print(f"总和:{total}") print(f"平均值:{average:.2f}") # 类型转换函数 user_input = "123" number = int(user_input) if user_input.isdigit() else 0 float_number = float(user_input) if user_input.replace('.', '').isdigit() else 0.0 print(f"转换后的整数:{number}") print(f"转换后的浮点数:{float_number}") # 序列函数 text = "hello world" characters = list(text) unique_chars = list(set(text)) sorted_chars = sorted(unique_chars) print(f"字符列表:{characters}") print(f"唯一字符:{unique_chars}") print(f"排序后的字符:{sorted_chars}")
对象的方法可以连续调用,形成链式表达式。这种模式在数据处理中特别常见。
|# 字符串方法链式调用 text = " HELLO, PYTHON WORLD! " processed = text.strip().lower().replace("world", "universe").title() print(f"处理后的文本:{processed}") # 列表方法链式调用结合列表推导式 data = ["apple", "Banana", "Cherry", "date"] normalized = [item.lower().strip() for item in data] sorted_data = sorted(normalized, key=len) print(f"标准化并排序:{sorted_data}") # 数字处理的链式调用 import math angle_degrees = 45 result = math.sin(math.radians(angle_degrees)) rounded_result = round(result, 4) print(f"sin(45°) = {rounded_result}")
在复杂的程序中,我们经常需要构建包含多种运算符和操作的复合表达式。理解运算符的优先级和结合性对于编写正确的表达式至关重要。
Python的运算符有着明确的优先级层次,从高到低依次为:函数调用、幂运算、一元运算、乘除法、加减法、比较运算、逻辑运算等。
|# 复杂表达式的优先级演示 a, b, c = 2, 3, 4 # 算术和比较的组合 result1 = a + b * c > 10 # 相当于 (a + (b * c)) > 10 print(f"a + b * c > 10 的结果:{result1}") # 逻辑和比较的组合 x, y, z = 5, 10, 15 complex_condition = x < y and y < z or x > 20 print(f"复杂条件的结果:{complex_condition}") # 函数调用的优先级 numbers = [1, 2, 3, 4, 5] avg_greater_than_three = sum(numbers) / len(numbers) > 3 print(f"平均值大于3:{avg_greater_than_three}")
虽然Python有明确的优先级规则,但使用括号来明确表达意图总是一个好习惯,这样可以提高代码的可读性。
|# 使用括号明确意图 price = 100 discount_rate = 0.1 tax_rate = 0.05 # 不清晰的表达式 unclear_total = price - price * discount_rate + price * tax_rate # 清晰的表达式 clear_total = price - (price * discount_rate) + (price * tax_rate) # 更清晰的分步计算 discount_amount = price * discount_rate tax_amount = price * tax_rate final_total = price - discount_amount + tax_amount print(f"不清晰计算:{unclear_total}") print(f"清晰计算:{clear_total}") print(f"分步计算:{final_total}")
逻辑运算符and和or具有短路求值的特性,这在某些情况下可以提高程序效率并避免错误。
|# 短路求值的应用 def expensive_operation(): print("执行了耗时操作") return True # 短路避免不必要的计算 flag = False result = flag and expensive_operation() print(f"短路结果:{result}") # 短路避免错误 data = [] has_data = len(data) > 0 and data[0] > 10 print(f"安全检查结果:{has_data}") # 使用短路设置默认值 user_input = "" name = user_input or "匿名用户" print(f"用户名:{name}")
当表达式变得非常复杂时,适当的分解和命名中间结果可以大大提高代码的可读性和可维护性。
|# 复杂嵌套表达式的分解 students = [ {"name": "小明", "scores": [85, 90, 78]}, {"name": "小红", "scores": [92, 88, 95]}, {"name": "小刚", "scores": [76, 84, 80]} ] # 一次性的复杂表达式(不推荐) complex_result = sum(sum(student["scores"]) / len(student["scores"]) for student in students) / len(students) # 分解后的清晰表达式(推荐) student_averages = [] for student in students: student_average = sum(student["scores"]) / len(student["scores"]) student_averages.append(student_average) class_average = sum(student_averages) / len(student_averages) print(f"复杂表达式结果:{complex_result:.2f}") print(f"分解表达式结果:{class_average:.2f}") # 使用列表推导式的中等复杂度表达式 class_average_comprehension = sum(sum(s["scores"])/len(s["scores"]) for s in students) / len(students) print(f"推导式结果:{class_average_comprehension:.2f}")
|2 + 3 * 4
|5 > 3 and 2 < 4 or False
|name = "World" result = f"Hello, {name}"
|[1, 2, 3] * 2
|2 ** 3 ** 2
7. 算术表达式练习
编写一个程序,定义两个数字变量,使用各种算术运算符计算结果并输出。
|# 定义两个数字变量 a = 15 b = 4 # 使用各种算术运算符 print(f"加法:{a} + {b} = {a + b}") print(f"减法:{a} - {b} = {a - b}") print(f"乘法:{a} * {b} = {a * b}") print(f"除法:{a} / {b} = {a / b}") print(f"整数除法:{a} // {b} = {a // b}") print(f"取余:{a} % {b} = {a % b}") print(f"幂运算:{a} ** {b} = {a ** b}")
输出结果:
|加法:15 + 4 = 19 减法:15 - 4 = 11 乘法:15 * 4 = 60 除法:15 / 4 = 3.75 整数除法:15 // 4 = 3 取余:15 % 4 = 3 幂运算:15 ** 4 = 50625
8. 比较和逻辑表达式
编写一个程序,使用比较运算符和逻辑运算符组合条件,判断学生的成绩等级和是否及格。
|# 学生成绩 score = 85 # 使用比较运算符判断等级 if score >= 90: grade = "A" elif score >= 80: grade = "B" elif score >= 70: grade = "C" elif score >= 60: grade = "D" else: grade = "F" # 使用逻辑表达式判断是否及格 passed = score >= 60 # 输出结果 print(f"成绩:{score}分") print(f"等级:{grade}") print(f"是否及格:{passed}") # 使用条件表达式(三元运算符) grade_ternary = "A" if score >= 90 else "B" if score >= 80 else "C" if score >= 70 else "D" if score >= 60 else "F" print(f"使用条件表达式得到的等级:{grade_ternary}")
输出结果:
|成绩:85分 等级:B 是否及格:True 使用条件表达式得到的等级:B
9. 字符串表达式练习
编写一个程序,创建字符串变量,使用连接运算符、f-字符串和字符串方法处理文本。
|# 创建两个字符串变量 first_name = "张" last_name = "三" # 使用连接运算符组合字符串 full_name = first_name + last_name print(f"完整姓名:{full_name}") # 使用f-字符串格式化输出 age = 20 city = "北京" intro = f"我是{full_name},今年{age}岁,来自{city}。" print(intro) # 使用字符串方法处理文本 text = " Hello Python World " print(f"原始文本:'{text}'") print(f"去除空格:'{text.strip()}'") print(f"转换为大写:'{text.strip().upper()}'") print(f"首字母大写:'{text.strip().capitalize()}'") # 检查字符串包含关系 sentence = "Python是一门优秀的编程语言" has_python = "Python" in sentence has_java = "Java" in sentence print(f"包含'Python':{has_python}") print(f"包含'Java':{has_java}")
输出结果:
|完整姓名:张三 我是张三,今年20岁,来自北京。 原始文本:' Hello Python World ' 去除空格:'Hello Python World' 转换为大写:'HELLO PYTHON WORLD' 首字母大写:'Hello python world' 包含'Python':True 包含'Java':False