跳转到正文

第一章:变量、基本数据类型与基础运算符

更新时间: 2026-10-10 13:30 · 中文版
目录 (18)

章节导航:上一章:第零章 环境配置与开发工具 | 下一章:第二章 函数

在业务处理与数据分析中,不同数据具有不同的特征:商品库存与交易笔数是整数,价格与利率是小数,姓名和订单号是文本,优惠资格则是“是/否”的逻辑状态。

计算机通过数据类型分类和存储这些信息。本章介绍 Python 代码文件的创建与运行方法,讲解数值、文本与布尔值三类基础数据类型,以及变量的赋值与基本运算规则。


第一部分:核心内容

1.1 代码的载体与工作空间:从 .py 文件到 VS Code 项目

1.1.1 为什么使用 .py 文件:代码的持久化与复用

交互式命令行适合快速测试,但终端关闭后代码即丢失。实际的数据处理通常需要重复运行、校验和协作维护,因此必须将代码保存到文件中。

  • Python 源文件(.py): Python 代码以纯文本形式保存在 .py 文件中(如 chapter_01.py),也称脚本文件。运行该文件时,Python 解释器自顶向下逐行读取并执行指令。
  • 两类基础语法元素:
    • 注释(Comment):以 # 开头的内容。解释器自动忽略,用于向阅读者解释代码意图与业务背景;
    • 输出函数(print):与交互式命令行不同,脚本中的计算结果不会自动打印,需调用 print(...) 显式输出到终端。

1.1.2 在 VS Code 中构建 learn_python 项目工作区

在软件工程与商业数据分析中,标准实践是为整个课程或任务建立一个专门的项目工作区(Workspace),将所有代码与依赖数据集中存放于统一的根目录下。

在 VS Code 中构建课程项目 learn_python 的步骤如下:

  1. 新建项目根文件夹:
    • 打开操作系统的“文件资源管理器”;
    • 在磁盘中选择一个固定的工作目录(强烈建议路径全程由英文字母、数字或下划线组成,避免中文路径或空格,以杜绝潜在的编码兼容问题),例如 D:\learn_python(或个人用户目录下的固定路径);
    • 在选定位置新建文件夹,命名为 learn_python。
  2. 在 VS Code 中打开项目文件夹:
    • 启动 Visual Studio Code 编辑器;
    • 点击顶部菜单栏的“文件”(File)→ 选择“打开文件夹...”(Open Folder...)(快捷键为 Ctrl + K Ctrl + O);
    • 在文件浏览器中选中刚刚创建的 learn_python 文件夹,点击“选择文件夹”;
    • 若界面弹出“是否信任此文件夹中的文件的作者”安全提示,勾选“信任父文件夹中的所有文件”后,点击“是,我信任此作者”(Yes, I trust the authors);
    • 此时,查看 VS Code 左侧活动栏的“资源管理器(Explorer)”面板,最顶端会显示文件夹名称 learn_python。这标志着 VS Code 已经成功将该文件夹作为当前项目的根目录打开。
  3. 核对 Python 解释器配置:
    • 当工程中存在.py文件时,查看 VS Code 界面右下角底部的状态栏,确认是否已正确绑定我们在第零章配置的 Python 解释器环境(例如显示 Python 3.12.x ('base': conda));
    • 如果状态栏显示“选择解释器”,可按下快捷键 Ctrl + Shift + P 打开命令面板,输入 Python: Select Interpreter,在下拉列表中点击选择对应的 Conda 或 Python 运行环境。

1.1.3 构建 chapter_01.py 文件并运行

建立好项目工作区后,我们在该项目下创建第一章的代码文件 chapter_01.py:

  1. 新建代码文件:

    • 将鼠标光标悬停在 VS Code 左侧资源管理器顶部的 learn_python 栏目上;
    • 点击右侧出现的“新建文件”图标(带有加号的小文件图标);
    • 在输入框中输入文件名:chapter_01.py,按回车键(Enter)确认;
    • 编辑器主区域随即打开一个空白的 chapter_01.py 代码标签页。
  2. 编写首段验证代码: 在 chapter_01.py 的编辑区中输入以下代码。通过头部注释标明课程与功能,并用 print(...) 打印一条系统启动信息:

    python
    # chapter_01.py
    # 课程:Computer Programming in Python
    # 任务:构建项目环境并输出电商交易系统运行状态
    
    print("===== 电商交易核算系统 =====")
    print("项目工作区: learn_python")
    print("系统状态: 运行正常")
    

    代码说明:

    • 头部注释(第 1~3 行):以 # 开头的内容为注释(Comment)。注释仅供人阅读,Python 解释器在执行时会自动忽略它,既不执行也不会输出。此处用于标注文件名、课程与任务;
    • 输出语句(第 5~7 行):print(...) 是 Python 内置的输出函数,用于将括号内的文本打印到终端。成对的双引号 "" 用于界定文本内容(引号本身不打印),每条 print() 语句输出后会自动换行。
  3. 保存代码文件: 在编辑区按下键盘快捷键 Ctrl + S(Mac 为 Cmd + S)。可以看到标签页标题右侧的实心圆点消失(恢复为关闭用的 × 图标),表示代码已写入磁盘。请养成每次运行前按 Ctrl + S 保存文件的习惯,未保存的文件不会被解释器执行最新改动。

  4. 运行代码并查看终端结果: 在 VS Code 中运行当前 .py 脚本有两种便捷方式:

    • 方式一(快捷按钮):点击编辑器右上角的三角播放图标(悬停提示为“在专用终端中运行 Python 文件”);
    • 方式二(右键菜单):在代码编辑区的任意空白位置点击鼠标右键,在弹出的上下文菜单中选择“在终端中运行 Python 文件”。

    点击后,VS Code 底部会自动弹出集成终端(Terminal)面板,Python 解释器读取 chapter_01.py 并输出结果:

    text
    ===== 电商交易核算系统 =====
    项目工作区: learn_python
    系统状态: 运行正常
    

看到终端输出上述三行内容,表明 learn_python 项目与 chapter_01.py 已经成功联通并正确运行。在后续各个小节中,讲义中的所有变量赋值、数据计算与案例代码,都可以在 chapter_01.py 中依次输入并运行验证。


1.2 变量与赋值

1.2.1 变量的概念:给数据起名字

在计算过程中,如果直接使用具体的数字或文字,代码不易看懂,也不方便在后面的计算中重复使用。**变量(Variable)**的作用,就是给具体的数据起一个名字,方便后续引用。

在 Python 中,可以使用等号 = 把数据赋值给一个变量:

案例:使用变量分别记录一件商品的基本交易信息,包括商品名称(文本)、单价(小数)、购买数量(整数)以及是否为会员(布尔值)。

python
# 记录一份商品交易信息
item_name = "无线降噪耳机"    # 文本,记录商品名称
unit_price = 299.0           # 小数,记录商品单价(元)
quantity = 3                 # 整数,记录购买数量(件)
is_member = True             # 布尔值,记录是否为会员

print(item_name)
print(unit_price)
print(quantity)
print(is_member)

输出:

text
无线降噪耳机
299.0
3
True

1.2.2 赋值语句的执行过程

在 Python 中,赋值操作也称为名称绑定(Name Binding)。

执行语句 account_balance = 1000.0 时,计算机会按照“先右后左”的顺序执行:

  1. 先计算等号右边的内容,得到一个值;
  2. 再把等号左边的变量名与这个值绑定。

变量本身没有固定的类型,它只是指向具体数据的名字。如果给一个已经存在的变量赋新值,这个变量名就会指向新的数据:

案例:把账户余额从 1000 元更新为 850 元,再查看变量记录的值。

python
account_balance = 1000.0   # 初始余额为 1000.0 元
expenditure = 150.0        # 支出为 150.0 元
account_balance = account_balance - expenditure  # 变量指向新的数值 850.0
print("final balance:", account_balance)  # print括号里可以包含多个打印项,用逗号隔开

输出:

text
final balance: 850.0

1.2.3 变量命名规则

规范的命名可以让代码更容易阅读和修改。在 Python 中,给变量起名字需要遵守以下规则和习惯:

  • 命名规则与课程约定:Python 也允许符合规则的中文变量名。本课程规定使用英文字母、数字和下划线 _;变量名不能以数字开头,也不能使用 if、class 等保留关键字。
  • 区分大小写:Price、price 和 PRICE 会被当作三个不同的变量;
  • 下划线命名法(snake_case):建议全部使用小写字母,单词之间用下划线连接,例如 monthly_sales、discount_rate、customer_id;
  • 尽量表达清楚含义:尽量不用无意义的单个字母,建议使用含义清晰的单词(例如用 quantity 表示数量,用 unit_price 表示单价)。

1.2.4 为什么使用变量:从“硬编码”到数据的变量化表示

在编写计算程序时,初学者常常产生一个疑问:“既然 Python 可以直接当作计算器使用,为什么不直接把数字写进表达式,而要专门定义变量呢?”

如果不使用变量,直接在代码中写入具体数值的做法称为硬编码(Hardcoding)。硬编码不仅降低了代码的可读性,更会在数据发生变动时引发严重的维护危机。

案例:某电商网店结算三笔不同商品的订单。初始规则中,每笔订单均包含 6.0 元的基础运费。

方式一:未使用变量(直接硬编码数值)

python
# 订单 1:单价 30.0 元,购买 2 件,基础运费 6.0 元
total_1 = 30.0 * 2 + 6.0
print("订单 1 实付:", total_1)

# 订单 2:单价 100.0 元,购买 1 件,基础运费 6.0 元
total_2 = 100.0 * 1 + 6.0
print("订单 2 实付:", total_2)

# 订单 3:单价 120.0 元,购买 3 件,基础运费 6.0 元
total_3 = 120.0 * 3 + 6.0
print("订单 3 实付:", total_3)

输出:

text
订单 1 实付: 66.0
订单 2 实付: 106.0
订单 3 实付: 366.0

这种直接写死数字的代码存在两个明显缺陷:

  1. 含义不明确:对于阅读代码的人而言,算式末尾的 6.0 缺乏业务语境,无法直接判断它究竟是运费、包装费还是平台服务费;
  2. 难以应对业务变动:假设由于物流调价,平台统一将基础运费由 6.0 元调整为 10.0 元。此时,开发者必须翻阅整段代码,在每一笔订单的算式中逐一找到 6.0 并手工修改为 10.0。如果程序中包含数十笔甚至上百笔订单,逐处修改不仅繁琐耗时,而且一旦中途疏漏了某一笔订单(例如改了订单 1 和 3,却漏改了订单 2),就会导致系统内部采用两套矛盾的计费标准,产生隐蔽而严重的业务 Bug。

方式二:使用变量集中管理公共数据

若使用变量提取出公共数据并赋予其清晰的名称,代码的结构将显著优化:

python
# 集中定义公共业务参数
shipping_fee = 6.0  # 基础运费(元)

# 订单 1:单价 30.0 元,购买 2 件
total_1 = 30.0 * 2 + shipping_fee
print("订单 1 实付:", total_1)

# 订单 2:单价 100.0 元,购买 1 件
total_2 = 100.0 * 1 + shipping_fee
print("订单 2 实付:", total_2)

# 订单 3:单价 120.0 元,购买 3 件
total_3 = 120.0 * 3 + shipping_fee
print("订单 3 实付:", total_3)

输出:

text
订单 1 实付: 66.0
订单 2 实付: 106.0
订单 3 实付: 366.0

通过引入变量,程序获得了两项关键优势:

  • 自解释性:变量名 shipping_fee 清晰标明了该数据的业务属性,消除了神秘的“魔术数字”;
  • 单一修改点:当运费上调为 10.0 元时,只需修改第一行的变量赋值(shipping_fee = 10.0)。后续所有引用该变量的订单计算语句均无需做任何改动,重新运行程序即可自动全部基于新运费完成核算,彻底消除了遗漏修改的隐患。

由此可见,使用变量的真正价值不仅在于给数据起名字以提高可读性,更在于通过“集中定义、多处引用”建立起单一修改源,大幅提升代码的可维护性与稳健性。


习题:某数码专营店需要核算商品“人体工学键盘”的单日库存变动。请编写一段 Python 代码完成以下任务:

  1. 遵循下划线命名法(snake_case)定义变量,记录初始库存为 100 件;
  2. 定义当日出库销售量为 28 件,通过赋值语句更新剩余库存;
  3. 定义当日补货入库量为 45 件,再次通过赋值语句更新最终库存;
  4. 使用 print(...) 语句同时输出提示文字与最终数值(预期终端输出:最终库存: 117)。

参考答案:

python
# 1. 记录初始库存
stock_quantity = 100

# 2. 销售出库 28 件并更新库存
sales_count = 28
stock_quantity = stock_quantity - sales_count

# 3. 补货入库 45 件并更新库存
restock_count = 45
stock_quantity = stock_quantity + restock_count

# 4. 打印最终盘点结果
print("最终库存:", stock_quantity)

输出:

text
最终库存: 117

1.3 数值类型:整数与浮点数

Python 中常用的数值类型主要有两种:

  • 整数(int):用于表示没有小数部分的数,例如销量、访问人数、期数、天数等。Python 整数没有固定的精度上限,可以表示很大的数;实际计算仍受可用内存等限制;
  • 浮点数(float):用于表示带有小数部分的数,例如价格、利率、温度、比率等。

1.3.1 常见的算术运算

Python 中常用的算术运算符如下:

运算符 运算名称 示例表达式 运算结果 说明
+ 加法 100 + 35 135 计算两数之和
- 减法 100 - 35 65 计算两数之差
* 乘法 50 * 0.8 40.0 计算两数之积
/ 真除法(浮点除) 10 / 4 2.5 计算两数相除的精确商,结果始终为浮点数
// 整除(向下取整) 10 // 4 2 计算两数相除的商并向下取整(地板除),返回不超过实际商的最大整数
% 取模(求余数) 10 % 4 2 计算两数相除的余数,满足恒等式 a == (a // b) * b + (a % b)
** 幂运算(乘方) 2 ** 3 8 计算以左操作数为底、右操作数为指数的幂值(即 x^y)

案例:演示基础加法运算,将基本工资与绩效奖金相加计算出当月总收入。

python
base_salary = 8000
performance_bonus = 2500
total_income = base_salary + performance_bonus
print(total_income)

输出:

text
10500

案例:演示整除 // 与取模 % 的配合使用,将总天数换算为“整周数”以及“不足一周的剩余天数”。

python
total_days = 45
weeks = total_days // 7
remaining_days = total_days % 7
print("剩余", weeks, "周", remaining_days, "天")

输出:

text
剩余 6 周 3 天

注意两条运算规则:

  1. 对本章的整数、浮点数使用 /,得到浮点数:即使两个数能够整除,例如 8 / 4,计算结果也是浮点数 2.0,而不是整数 2。
  2. 整除 // 会向下取整:取不超过实际商的最大整数值;操作数中有浮点数时,结果也用浮点数表示。对于正数运算,9 // 2 得到 4;对于负数运算,-9 // 2 的结果是 -5(因为实际商为 -4.5,向下取整得到 -5)。

1.3.2 复合赋值运算

在做数值累计或逐步调整数值时,可以使用复合赋值运算符简化书写:

案例:使用复合赋值运算符 += 和 -= 记录账户资金存入与支出的连续变动。

python
balance = 500.0
balance += 200.0   # 等价于: balance = balance + 200.0
balance -= 50.0    # 等价于: balance = balance - 50.0
print(balance)

输出:

text
650.0

案例:使用复合赋值运算符 *= 对商品价格进行打折计算并更新价格变量。

python
price = 120.0
price *= 0.85      # 打八五折,等价于: price = price * 0.85
print(price)

输出:

text
102.0

1.3.3 实际计算示例

装箱数量与运费计算

案例:结合整除 // 与取模 %,计算电商发货时所需的整箱数和剩余散件数,并分别核算整箱与散件的运费总和。

某电商仓库发货规则如下:每个纸箱装 12 件商品。现有 125 件同规格商品待发运:

  • 整箱商品走标准货运,每箱运费 30 元;
  • 不足一箱的剩余散件走普通快递,每件运费 5 元。

电商装箱与运费计算图示

python
total_items = 125
box_capacity = 12

full_boxes = total_items // box_capacity      # 计算整箱数
loose_items = total_items % box_capacity      # 计算散件数

shipping_cost = (full_boxes * 30) + (loose_items * 5)

print("整箱数量:", full_boxes)
print("零散件数:", loose_items)
print("总运费(元):", shipping_cost)

输出:

text
整箱数量: 10
零散件数: 5
总运费(元): 325
资金复利终值计算

案例:使用乘方运算符 ** 计算固定年化收益率下的资金复利终值(本息合计)。

某企业将一笔 10,000 元的流动资金存入银行定期理财,年化复利收益率为 5%(即 0.05),存期为 2 年。

复利终值的计算公式为:

FV = PV \times (1 + r)^n

其中 PV 为初始本金,r 为年化收益率,n 为存期年数。计算 2 年到期后的本息合计金额:

python
principal = 10000.0     # 初始本金(元)
annual_rate = 0.05      # 年化收益率(5%)
years = 2               # 存期(年)

# 使用 ** 运算符计算复利终值
future_value = principal * ((1 + annual_rate) ** years)

print("初始本金(元):", principal)
print("2年期满本息合计(元):", future_value)

输出:

text
初始本金(元): 10000.0
2年期满本息合计(元): 11025.0

1.4 字符串类型:文本数据

姓名、订单编号和收货地址都可以用**字符串(str)**表示。

1.4.1 书写与拼接字符串

单引号 '...' 和双引号 "..." 都用于书写字符串,前后的引号需要匹配。两个字符串可以用 + 拼接。

案例:记录客户姓名和商品名称,将它们组合成一条购买记录。

python
customer_name = '李明辉'
product_name = "燕麦奶"
message = customer_name + "购买了" + product_name  # +在这里不是数值相加,而是字符串拼接
print(message)

输出:

text
李明辉购买了燕麦奶

案例扩展:从独立的 JSON 数据文件中提取字段并使用 f-string 格式化

在实际商业系统与数据开发中,业务数据通常保存在独立的文件中(例如 order.json),或由数据库查询导出为结构化的 JSON(JavaScript Object Notation) 格式。

下载示例订单数据,将文件以 order.json 名称保存到项目工作区。

假设在项目工作区目录下存在一个独立的订单文件 order.json:

json
{
    "order_id": "ORD-20260922-001",
    "customer_name": "李明辉",
    "product_name": "燕麦奶",
    "quantity": 2,
    "total_price": 48.0
}

Python 标准库提供了 json 模块。使用 open(...) 打开文件后,调用 json.load(file) 即可直接将文件流中的 JSON 数据解析为映射结构。

此外,相比使用 + 重复拼接字符串,现代 Python 推荐使用 格式化字符串(f-string):在字符串引导引号前添加前缀 f,并在花括号 {} 内直接填入变量,文本模板清晰且不易出错。

python
import json

# 1. 打开并读取当前工作区下的 order.json 文件
with open("order.json", "r", encoding="utf-8") as file:
    order_data = json.load(file)

# 2. 从解析后的数据中提取目标字段
customer_name = order_data["customer_name"]
product_name = order_data["product_name"]

# 3. 使用 f-string 格式化构建消息并打印
message = f"{customer_name}购买了{product_name}"
print(message)

输出:

text
李明辉购买了燕麦奶

1.4.2 索引与切片

索引是字符的位置编号。从左向右从 0 开始;从右向左,最后一个字符的索引为 -1。

切片用于取出一段文本。s[start:stop] 从索引 start 开始,取到 stop 之前。省略 start 表示从开头取,省略 stop 表示取到末尾。

案例:从报告标题中取出首尾字符、英文部分和中文部分。

python
report_title = "Python商业数据分析指南"
print(report_title[0])      # 正向索引 0,取出首字符
print(report_title[-1])     # 反向索引 -1,取出末尾字符
print(report_title[0:6])    # 切片取出英文部分(索引 0 到 5,不包含 6)
print(report_title[6:])     # 切片取出中文部分(从索引 6 取到末尾)

输出:

text
P
南
Python
商业数据分析指南

[0:6] 取出索引 0 到 5 的六个字符,不包含索引 6。两段 s[:k] 与 s[k:] 拼接起来仍是原字符串。

没给定起始索引时,切片会默认从 0 开始;
没给定结束索引时,切片会默认到字符串末尾。

1.4.3 字符串不可修改

字符串中的字符不能直接改写。可以通过拼接、截取或替换取得处理后的字符串,再把它赋给变量;原字符串的内容不会因此改变。

案例:把商品编号最后的 A 改为 B,同时保留原编号。

python
product_code = "SKU-2024-A"
new_product_code = product_code[:-1] + "B"
print(product_code)
print(new_product_code)

# 取消下一行的注释会引发 TypeError:字符串不支持直接修改字符。
# product_code[-1] = "B"

输出:

text
SKU-2024-A
SKU-2024-B

1.4.4 常用字符串方法

字符串.方法名(...) 表示对这个字符串执行相应操作。下面的方法都会返回处理结果;需要保留结果时,用变量接收。

案例:去掉客户姓名两端的空格,得到可以放入通知中的姓名。strip() 去除首尾空白字符,包括空格和换行符。

python
raw_name = "   李明辉   "
customer_name = raw_name.strip() # 去掉raw_name字符串首尾的空白字符后,将结果赋给customer_name
print(customer_name)

输出:

text
李明辉

案例:更新通知中的配送状态。replace(old, new) 将匹配的旧文本替换为新文本。

python
message = "配送状态: 等待取件"
updated_message = message.replace("等待取件", "已出库")  # 替换掉message字符串中的旧字符串后,将结果赋给updated_message

print(updated_message)

输出:

text
配送状态: 已出库

案例:将优惠码转成大写,将邮箱地址中的英文字母转成小写,观察 upper() 与 lower() 的结果。

python
coupon_code = "spring2026sale"
email = "STUDENT@EXAMPLE.COM"
print(coupon_code.upper())  # 将coupon_code字符串中的所有小写字母转成大写字母后,将结果传递给print函数打印到终端
print(email.lower())      # 将email字符串中的所有大写字母转成小写字母后,将结果传递给print函数打印到终端

输出:

text
SPRING2026SALE
student@example.com

1.4.5 格式化字符串(f-string)

在字符串引号前加上前缀 f(即 f-string)。在花括号 {} 中,不仅可以直接传入变量的值,还可以通过格式说明符对变量的值进行格式化。例如 {amount:.2f} 表示将 amount 格式化为保留两位小数显示;这种格式化只改变生成的文本,不会修改变量本身的数值。

案例:把客户姓名与订单金额组合成付款通知,金额显示两位小数。

python
customer_name = "赵琳"
order_amount = 4520.3789
message = f"客户 {customer_name},订单金额: ¥{order_amount:.2f}"
print(message)

输出:

text
客户 赵琳,订单金额: ¥4520.38
用计算结果生成通知

案例:按固定年利率计算五年后的本息合计,并用两位小数显示结果。

本例假定每年把利息计入本金,下一年继续计息,计算公式为:

F = P \times (1 + r)^t

其中 P 为投资本金,r 为年利率,t 为投资期限(年)。计算 10 万元本金在年利率 3.5\% 的条件下,存满 5 年后的本息总额:

python
principal = 100000.0   # 本金: 100,000 元
annual_rate = 0.035    # 年利率: 3.5%
years = 5              # 投资期限: 5 年

future_value = principal * ((1 + annual_rate) ** years)
print(f"5 年后本息合计: {future_value:.2f} 元")

输出:

text
5 年后本息合计: 118768.63 元

案例:给定 phone_number = "13812345678",用切片和拼接把中间四位换成 ****,得到 138****5678。先写出要保留的两段,再组合结果。

python
phone_number = "13812345678"
masked_number = f"{phone_number[:3]}****{phone_number[7:]}"  # f-string
# masked_number = phone_number[:3] + "****" + phone_number[7:]  # 字符串连接
print(masked_number)

输出:

text
138****5678

1.5 布尔类型与条件逻辑

在很多业务场景中,我们需要判断某个条件是否成立(例如余额是否足够、是否满足优惠条件)。这种表示“成立”或“不成立”的状态用布尔类型(bool)表示,它只有两个值:True(真)和 False(假),注意首字母大写。

True 和 False 属于 Python 的保留关键字(Keyword)。关键字是编程语言内部预先定义、具有固定语法用途的专用标识符。使用关键字时需要遵守以下规则:

  • 不可用作变量名或重新赋值:关键字不能作为普通变量名使用,也不能改变其取值(例如执行 True = 1 会直接引发语法错误 SyntaxError: cannot assign to True);
  • 严格区分大小写:Python 区分大小写,只有首字母大写的 True 与 False 才是布尔值。若误写为全小写的 true 或 false,Python 会将其识别为普通变量名;若该变量未预先定义,会引发名称错误 NameError。

本节后续介绍的逻辑运算符 and、or、not 同样属于 Python 的保留关键字。关于查询当前运行环境中完整保留关键字列表的方法,可参见本章扩展知识点中的 1.11 节。

1.5.1 比较运算符

对本章的数字或字符串进行适用的比较,可以判断大小或相等关系,得到布尔值:

运算符 含义 示例表达式 运算结果
== 等于(两边的值是否相等) 50 == 50.0 True
!= 不等于 100 != 80 True
> 大于 3500 > 3000 True
< 小于 1.2 < 1.0 False
>= 大于或等于 100 >= 100 True
<= 小于或等于 60 <= 55 False

案例:通过比较运算符 >= 比较账户现有余额与支付金额,判断当前资金是否足以支付。

python
account_balance = 420.0
payment = 450.0

has_enough_funds = account_balance >= payment
print(f"账户余额是否充足: {has_enough_funds}")

输出:

text
账户余额是否充足: False

案例:通过比较运算符 == 校验用户输入的优惠兑换码与系统设定的有效码是否一致。

python
input_code = "SPRING20" # 用户输入的优惠码,可能来自网页输入
valid_code = "SPRING20" # 系统设定的有效码,可以从数据库获取

# == 用于判断两边的值是否相等;注意不要误写为单个等号 =(赋值)
is_code_valid = input_code == valid_code
print(f"优惠码是否有效: {is_code_valid}")

输出:

text
优惠码是否有效: True

注意区分 = 与 ==: 单个等号 = 是赋值运算符,用于将数据保存到变量中(例如 payment = 450.0);双等号 == 是比较运算符,用于判断两边的值是否相等,运算结果是布尔值 True 或 False。

1.5.2 逻辑运算符与短路求值

当需要组合多个条件时,可以使用 and(且)、or(或)、not(非)。本节用它们组合布尔值或比较表达式:

  • and(逻辑且):所有条件都为真时,结果才为 True;
  • or(逻辑或):只要有一个条件为真,结果就是 True;
  • not(逻辑非):把真假结果取反。

案例:组合使用 or、and 和 not,根据订单金额是否达标、是否为会员、是否处于受限名单等多项规则,综合判断客户是否享受免运费权益。

python
# 电商促销包邮条件判断:
# 规则: 订单满 99 元 或 属于会员,且 客户不在受限名单中
cart_total = 85.0
is_vip = True
is_restricted = False

qualifies_free_shipping = (cart_total >= 99.0 or is_vip) and (not is_restricted)
print(f"是否享受免运费: {qualifies_free_shipping}")

输出:

text
是否享受免运费: True

布尔变量的命名习惯: 在 Python 编程实践中,布尔变量通常推荐使用 is_ 或 has_ 等前缀开头(遵循下划线命名法 snake_case):

  • is_ 前缀:表示“是否处于某种状态”或“是否具备某种属性”,例如上文中的 is_vip(是否为会员)、is_code_valid(验证码是否有效);
  • has_ 前缀:表示“是否具备某种资源或满足某种条件”,例如上文中的 has_enough_funds(资金是否充足)。

这种命名方式让变量名称读起来如同一个是非判断,使条件逻辑代码更具可读性。

短路求值(Short-Circuit Evaluation): Python 计算逻辑条件时,会根据前面的结果决定是否继续计算:

  • 在 A and B 中,如果 A 已经是 False,整个条件肯定不成立,Python 不会再去计算 B;
  • 在 A or B 中,如果 A 已经是 True,整个条件肯定成立,Python 也不会再去计算 B。

这个特点常用来避免除以零等报错情况:

案例:利用 and 的短路求值特性,在计算每笔交易的平均金额前先判断交易笔数是否大于 0,防止因笔数为零导致除以零报错。

python
transaction_count = 0
total_sales = 1000.0
# 若 transaction_count 为 0,前一个条件为 False,触发短路,不会执行后面的除法
is_high_average = (transaction_count > 0) and ((total_sales / transaction_count) > 200.0)
print(is_high_average)

输出:

text
False

1.6 类型检测与类型转换

Python 对数据类型有明确的区分。例如,文字 "50" 和数字 10 不能直接用 + 相加,否则程序会报错(TypeError)。

1.6.1 查看数据类型:type()

内置函数 type() 用来查看数据属于哪种类型:

案例:使用内置函数 type() 分别查看整数、浮点数、字符串和布尔值在 Python 中的具体类型名称。

python
print(type(500))
print(type(18.5))
print(type("上海"))
print(type(True))

输出:

text
<class 'int'>
<class 'float'>
<class 'str'>
<class 'bool'>

1.6.2 类型转换

当读到的价格或数量是文本时,需要先转换成数字,才能参与数值计算。下面先用字符串表示这些原始数据:

案例:将输入的文本格式单价与数量分别转换为浮点数与整数以进行打折计算,并将整数订单号转换为文本完成编码拼接。

python
# 1. 文本转换成数字
raw_price = "199.9"
clean_price = float(raw_price)       # 转换为浮点数
discounted_price = clean_price * 0.9
print(discounted_price)

raw_quantity = "25"
quantity = int(raw_quantity)         # 转换为整数
print(quantity + 5)

# 2. 数字转换成文本
order_id = 10086
order_code = "ORD-" + str(order_id)
print(order_code)

# 3. 浮点数转整数(直接去掉小数部分,不作四舍五入)
print(int(8.99))

输出:

text
179.91
30
ORD-10086
8

注意转换错误: 如果文字本身不是合法的数字形式,例如 int("abc") 或 int("12.5"),转换会直接报错(ValueError)。需要保留小数时使用 float()。可以尝试这些输入,阅读错误类型和出错位置。


核心内容练习

练习 1:订单通知与手机号脱敏

任务:清理客户姓名,将手机号中间四位替换为星号,计算已确定优惠金额后的实付款,生成订单通知。

已知 raw_name = " 李明辉 "、phone = "13812345678"、raw_total = "388.50"、payment_status = "PAID"。该订单已经满足满减条件,优惠金额为 40 元。

先清理姓名,再提取手机号两端的字符;把金额文本转成数字后计算实付款。预期输出:

text
客户 李明辉 (138****5678) 订单实付: ¥348.50,支付状态: PAID。

练习 2:判断余额是否足够

任务:计算购物总额,判断现有余额能否支付,并判断是否符合给定的免运费条件。

商品单价为 28.5 元,购买 4 件,账户余额为 120 元。免运费规则为“商品总额达到 99 元,或购买者是会员”;假定本次购买者不是会员。依次输出商品总额、余额是否足够支付商品总额、是否符合免运费条件。

预期结果分别为 114.0、True、True。再把余额改为 100 元,预测哪些结果会变化,运行核对。此题只判断条件,不要求根据条件选择不同的计算步骤。


第二部分:扩展知识点

以下内容可按需要选读。核心内容练习不要求使用扩展知识点中的列表、Decimal 或其他扩展用法。

1.7 空值:None

None 可以表示尚未提供的数据,例如没有填写的配送备注。它的类型是 NoneType,与数字 0、空字符串 "" 不同。

案例:记录尚未填写的配送备注,检查它是否为 None。

python
delivery_note = None
print(delivery_note is None)

输出:

text
True

is None 检查是否为 None 对象。is 比较对象身份,== 比较值;检查 None 通常使用 is None。Python 编写建议。

1.8 浮点数的小数误差

1.8.1 观察误差

案例:计算 0.1 + 0.2,查看结果是否与 0.3 完全相等。

python
result = 0.1 + 0.2
print(result)
print(result == 0.3)

输出:

text
0.30000000000000004
False

许多十进制小数无法用有限位二进制精确表示。常见 Python 实现使用有限精度的二进制浮点数保存 float,存储和运算时会发生舍入。例如,0.1 保存的近似值略大于精确的十分之一。浮点数说明。

金额显示为两位小数,只改变显示格式,不会消除底层数值的近似误差。

1.8.2 近似比较:math.isclose()

Python 自带的标准库包含一些可直接使用的工具。import math 把 math 模块引入当前程序,之后可以通过 math.功能名(...) 使用其中的功能。

案例:判断刚才的两个计算结果是否足够接近。

python
import math

val_a = 0.1 + 0.2
val_b = 0.3
print(math.isclose(val_a, val_b))

输出:

text
True

isclose() 根据允许的误差范围作比较。本例使用默认设置;处理测量或统计数据时,需要根据具体问题选择误差范围。

1.8.3 十进制计算:Decimal

decimal 是标准库模块,Decimal 是其中用于十进制计算的类型。from decimal import Decimal 将这个名称引入程序,随后可以直接使用 Decimal(...)。

案例:用金额文本建立 Decimal 数值,计算 0.1 与 0.2 的十进制和。

python
from decimal import Decimal

price_a = Decimal("0.1")
price_b = Decimal("0.2")
exact_sum = price_a + price_b
print(exact_sum)
print(exact_sum == Decimal("0.3"))

输出:

text
0.3
True

这里从字符串构造 Decimal,避免先把金额转换成二进制浮点数。Decimal 运算也有精度和舍入规则,例如三分之一仍无法写成有限位十进制小数;结算时还需要明确保留几位小数,以及何时、如何舍入。Decimal 说明。

1.9 其他数据的真值

bool(...) 可以查看一个值在条件判断中对应的真假结果。本章涉及的值中,None、False、0、0.0 和空字符串 "" 对应 False;非零数值和非空字符串对应 True。

案例:检查检索词是否为空,并观察文本 "False" 与布尔值 False 的区别。

python
search_term = "Python"
print(bool(search_term))
print(bool(""))
print(bool("False"))
print(bool(False))

输出:

text
True
False
True
False

bool("False") 为 True,因为它检查字符串是否为空,不会把单词翻译成真假值。

案例:检查评分是否缺失。评分 0.0 是已填写的正常数值,不能仅凭真值判断它是否缺失。

python
user_rating = 0.0
print(bool(user_rating))
print(user_rating is None)

输出:

text
False
False

and 和 or 可以返回参与运算的原值,并不总是返回布尔值。x or y 在 x 为真时返回 x,否则返回 y;x and y 在 x 为假时返回 x,否则返回 y。布尔操作说明。

案例:昵称为空时,使用默认显示名称。

python
nickname = ""
display_name = nickname or "未填写昵称"
print(display_name)

输出:

text
未填写昵称

将昵称改为自己的姓名,再运行观察。涉及 0 这样的有效数值时,需要先确认默认值规则是否适合。

1.10 多行文本、转义字符与原始字符串

1.10.1 多行文本

三引号可以书写跨越多行的字符串。

案例:把收货地址分成两行保存并显示。

python
shipping_address = """北京市海淀区
中关村南大街5号"""
print(shipping_address)

输出:

text
北京市海淀区
中关村南大街5号

1.10.2 转义字符

字符串中的反斜杠与后面的字符可以组成转义序列:\n 表示换行,\t 表示制表符,\\ 表示一个反斜杠。需要在字符串中写出与外层相同的引号时,可以使用 \' 或 \"。

案例:用 \n 将课程名称和教室安排显示在两行。

python
print("课程: Python\n教室: A203")

输出:

text
课程: Python
教室: A203

1.10.3 原始字符串

Windows 路径常用反斜杠,例如 C:\data\new_reports.csv。普通字符串中的 \n 会被当成换行。原始字符串在引号前加 r,保留这里的反斜杠。

案例:保存并显示一个 Windows 文件路径。

python
report_path = r"C:\data\new_reports.csv"
print(report_path)

输出:

text
C:\data\new_reports.csv

原始字符串也有书写限制:不能以奇数个反斜杠紧接结束引号。例如,需要表示目录末尾的一个反斜杠时,可用普通字符串中的 \\。字符串规则。

1.11 关键字与内置名称

if、for、class 等保留关键字有语法用途,不能用作普通变量名。keyword 模块可以查询它们。

案例:检查 class 与 price 是否为保留关键字。

python
import keyword

print(keyword.iskeyword("class"))
print(keyword.iskeyword("price"))

输出:

text
True
False

可以自行运行 print(keyword.kwlist) 查看当前 Python 版本的完整保留关键字列表。

str、sum、max 等是内置名称。把变量命名为 str,会使当前作用域中的 str 指向新值,妨碍后面用这个名字调用原来的功能。

案例:使用 order_id 保存订单编号,再用内置的 str() 把编号转换为文本。

python
order_id = 10086
order_code = "ORD-" + str(order_id)
print(order_code)

# 如果先执行 str = 500,再调用 str(order_id),会引发 TypeError。

输出:

text
ORD-10086

1.12 文本拆分与连接:认识列表结果

1.12.1 split() 与列表中的元素

**列表(list)**按顺序保存多个值,写在方括号 [] 中,用逗号分隔。split() 将字符串按指定分隔符拆分,返回一个列表。

案例:拆分包含城市、区名和邮编的文本,再取出其中的邮编。

python
raw_record = "   Beijing, Chaoyang, 100020   "
clean_record = raw_record.strip()
fields = clean_record.split(", ")
print(fields)
print(fields[2])

输出:

text
['Beijing', 'Chaoyang', '100020']
100020

fields[2] 取得列表中索引为 2 的第三个元素,这里是整个字符串 "100020";字符串索引则取得其中的一个字符。列表的增删改和遍历将在容器章节中介绍。

本例用的是逗号后跟一个空格的分隔符 ", "。把它改为 ",",比较返回的各段文本有何变化。

1.12.2 join() 连接文本

分隔符.join(列表) 可以用指定分隔符连接列表中的字符串元素。

案例:把年、月、日三个字符串连接成日期文本。

python
date_elements = ["2026", "09", "05"]
iso_date = "-".join(date_elements)
print(iso_date)

输出:

text
2026-09-05

这里三个元素都是字符串;join() 不会自动把数字转换为字符串。

1.13 编号补零

f-string 中的 :05d 把整数按至少五位宽度显示,不足的位数在前面补零。它不会把更长的整数截短。

案例:把整数编号 86 显示为五位编号 00086。

python
invoice_no = 86
print(f"编号: {invoice_no:05d}")

输出:

text
编号: 00086

扩展知识点练习

练习 1:解析完整订单记录

任务:拆分订单文本,提取姓名、手机号、金额和状态,生成与核心内容练习相同的通知。需要 §1.12 的列表与拆分知识。

原始数据为 raw_record = " USER:李明辉;PHONE:13812345678;TOTAL:388.50;STATUS:PAID "。本题保证四个字段齐全且顺序固定,订单已满足满减条件,优惠金额为 40 元。

先用分号拆分字段,再用冒号分开每个字段的名称与内容。提取手机号和金额后,完成脱敏、类型转换与实付款计算。预期输出:

text
客户 李明辉 (138****5678) 订单实付: ¥348.50,支付状态: PAID。

练习 2:比较两种分期方案

任务:按给定规则计算分期费用,分别用 float 与 Decimal 计算并比较结果。需要 §1.8 的 Decimal 知识。

账单本金为 12,000 元。方案 A 分 3 期,每期手续费为原始本金的 0.75%;方案 B 分 6 期,每期手续费为原始本金的 0.65%。本金在各期平均分摊。

计算每期本金、每期手续费、总手续费,以及 B 比 A 多出的总手续费。用下面的金额核对:

项目 方案 A 方案 B
每期本金 4,000 元 2,000 元
每期手续费 90 元 78 元
总手续费 270 元 468 元

两方案总手续费相差 198 元。这组数据的 float 与 Decimal 结果可能显示相同金额;结合 0.1 + 0.2 的例子,说明为什么一次结果相同不足以证明所有小数计算都精确。

参考资料

命名与类型的进一步说明可查阅 Python 标识符规则和内置类型。


章节导航:上一章:第零章 环境配置与开发工具 | 下一章:第二章 函数