第 3 天|变量、数据类型、比较与逻辑¶
日期: 2026 年 7 月 22 日
核心内容: 变量与赋值、命名规则、str/int/float/bool/None、类型检查、比较、逻辑、边界值
Python 中“看起来一样”的值可能具有不同类型。真题中的销量、退单量和售价如果是文本, 就不能可靠地做减法、乘法、排序和均值;筛选条件如果不是正确的布尔表达式,也会得到错误样本。
一、变量、值与赋值¶
quantity = 125
执行过程:
- 右边产生整数
125; - Python 建立名称
quantity; =让名称quantity指向这个整数对象。
可以先把变量理解为“贴在值上的标签”。变量不是固定的盒子,同一个名称可以重新指向新值:
quantity = 125
quantity = 130
第二次赋值后,quantity 的当前值是 130。Python 按从上到下的顺序执行,
后一次赋值会覆盖这个名称之前指向的值。
= 表示赋值;判断两个值是否相等使用 ==。不要把数学中的等号含义直接套到赋值语句上。
quantity = 125
print("第一次赋值:", quantity, type(quantity))
quantity = 130
print("重新赋值后:", quantity, type(quantity))
quantity = "130"
print("再次赋值后:", quantity, type(quantity))
第一次赋值: 125 <class 'int'> 重新赋值后: 130 <class 'int'> 再次赋值后: 130 <class 'str'>
二、Python 是动态类型语言¶
变量名称本身没有永久固定的类型,类型属于当前指向的值:
quantity = 125 # 当前指向 int
quantity = "125" # 当前改为指向 str
Python 允许这样做,但业务代码中不建议让同一变量在不同位置随意改变类型。 稳定做法是使用能提示阶段的变量名:
quantity_text = "125"
quantity = int(quantity_text)
类型标注可以表达预期,但不会在运行时自动强制:
quantity: int = 125
quantity = "125" # Python 仍能运行;编辑器或类型检查器可能警告
竞赛代码首先保证运行时类型正确,不能把类型标注当作自动转换或自动验证。
已经存在的数值变量可以使用复合赋值:
quantity += 5 # 等价于 quantity = quantity + 5
quantity -= 2
total *= 1.1
复合赋值前变量必须已经存在。注意 /= 通常会产生浮点数,即使原变量是整数。
三、变量命名规则¶
合法变量名可以包含英文字母、数字和下划线,但不能以数字开头,也不能使用 Python 关键字。
| 名称 | 是否推荐 | 原因 |
|---|---|---|
sales_quantity |
推荐 | 小写加下划线,业务含义明确 |
return_rate |
推荐 | 能看出保存的是退单率 |
x |
只适合短小临时计算 | 无法看出业务含义 |
2price |
非法 | 不能以数字开头 |
sales quantity |
非法 | 变量名中不能有空格 |
class |
非法 | class 是 Python 关键字 |
Sales 与 sales |
都合法但不同 | Python 严格区分大小写 |
销售数量 |
合法但不建议作为竞赛主变量 | 跨工具、协作和输入不方便 |
推荐使用 snake_case:
product_name
sales_quantity
return_quantity
unit_price
total_sales
import keyword
names = ["sales_quantity", "2price", "class", "销售数量"]
for name in names:
print(
name,
"基本格式合法:", name.isidentifier(),
"是否关键字:", keyword.iskeyword(name),
)
sales_quantity 基本格式合法: True 是否关键字: False 2price 基本格式合法: False 是否关键字: False class 基本格式合法: True 是否关键字: True 销售数量 基本格式合法: True 是否关键字: False
四、不要覆盖 Python 内置名称¶
以下名称虽然可以用作变量,但会覆盖常用内置工具:
str = "文本"
list = [1, 2, 3]
sum = 100
type = "VIP"
input = "完成"
例如执行 str = "文本" 后,再写 str(125) 会报
TypeError: 'str' object is not callable。
如果在 Notebook 中误覆盖了内置名称:
- 可以执行
del str删除当前变量; - 更稳妥的是修正变量名并重启内核;
- 建议改用
text_value、numbers、total、customer_type等名称。
pandas 常用别名 pd、NumPy 常用别名 np 也不要再用于保存其他值。
五、本阶段需要认识的五种值¶
| 类型/值 | 含义 | 示例 | 真题字段 |
|---|---|---|---|
str |
文本 | "双肩包" |
店铺名、商品名、付款方式 |
int |
整数 | 125 |
销量、退单量、年龄 |
float |
浮点数 | 199.0 |
售价、金额、占比 |
bool |
逻辑真或假 | True |
是否下一页、筛选条件 |
None |
暂无值、没有结果 | None |
接口缺失值的初步表示 |
文本需要引号;数值、True、False 和 None 不加引号,并且大小写固定。
"True"、"None" 都只是普通字符串。
六、检查类型:type() 与 isinstance()¶
type(value) 返回对象的具体类型:
type(125) # int
type("125") # str
isinstance(value, type_name) 返回布尔值,更适合程序判断:
isinstance(125, int) # True
isinstance(125, (int, float)) # True
type() 和 isinstance() 只检查,不会修改原值。需要改变类型要明确调用
int()、float()、str() 等转换函数。
一个容易忽略的细节:bool 是 int 的子类,所以 isinstance(True, int) 为 True。
如果业务字段只允许普通整数而不允许布尔值,可以写:
type(value) is int
或同时排除 bool:
isinstance(value, int) and not isinstance(value, bool)
product_name = "双肩包"
quantity = 125
mall_price = 199.0
is_over_100 = quantity > 100
coupon_code = None
print(product_name, type(product_name))
print(quantity, type(quantity))
print(mall_price, type(mall_price))
print(is_over_100, type(is_over_100))
print(coupon_code, type(coupon_code))
print("quantity 是数值:", isinstance(quantity, (int, float)))
双肩包 <class 'str'> 125 <class 'int'> 199.0 <class 'float'> True <class 'bool'> None <class 'NoneType'> quantity 是数值: True
代码解读¶
| 表达式 | 结果 |
|---|---|
product_name = "双肩包" |
保存文本 |
quantity = 125 |
保存整数 |
mall_price = 199.0 |
保存浮点数 |
quantity > 100 |
产生 True 或 False |
coupon_code = None |
明确表示当前没有优惠码 |
type(quantity) |
查询变量类型,不修改变量 |
isinstance(quantity, (int, float)) |
判断是否为整数或浮点数 |
print(product_name) 输出变量值;print("product_name") 输出英文文字本身。
七、字符串 str¶
字符串是字符序列,可使用单引号或双引号:
product_name = "双肩包"
payment_method = '支付宝'
常用基础操作:
| 表达式 | 结果 | 含义 |
|---|---|---|
"商" + "品" |
"商品" |
拼接文本 |
"A" * 3 |
"AAA" |
重复文本 |
len("双肩包") |
3 |
字符数量 |
" 包 ".strip() |
"包" |
删除两端空白 |
"VIP".lower() |
"vip" |
转为小写 |
字符串中的数字仍然是文本:
"12" + "3" # "123"
12 + 3 # 15
str 和 int 不能直接相加:"销量:" + 125 会触发 TypeError。
可使用 str(125) 或下一天学习的 f-string。
八、整数 int¶
整数没有小数部分,可以为正数、负数或零:
sales_quantity = 125
return_quantity = 8
stock_change = -3
zero_sales = 0
Python 整数可以很大,不受常见 32 位整数范围限制;但进入 pandas、Excel 或数据库后,
可能转换成有固定范围的 int64 等类型。
大整数可用下划线提高可读性:
annual_sales = 1_250_000
下划线不改变数值,1_250_000 == 1250000 为 True。
业务阈值如果希望按“常量”管理,通常使用全大写名称:
MIN_SALES_QUANTITY = 100
MAX_RETURN_RATE = 0.10
全大写只是团队约定,Python 不会禁止后续重新赋值。
九、浮点数 float 与精度¶
float 用于带小数的数值,但计算机以二进制近似保存许多十进制小数:
result = 0.1 + 0.2
print(result)
print(result == 0.3)
print(round(result, 2))
0.30000000000000004 False 0.3
处理浮点数时:
- 展示金额可以使用
round(value, 2)或格式化为两位小数; - 判断两个计算结果是否接近,可使用
math.isclose(); round()改变的是返回结果,不会自动修改原变量;- 对必须精确到分的财务结算,可使用整数“分”或
decimal.Decimal; - pandas 中的浮点列也会受到相同的二进制精度影响。
from math import isclose
isclose(0.1 + 0.2, 0.3) # True
精确十进制示例:
from decimal import Decimal
amount = Decimal("0.1") + Decimal("0.2")
print(amount) # 0.3
创建 Decimal 时优先传入字符串,不要先写成已经近似的浮点数。
十、数值运算后的类型¶
| 表达式 | 结果 | 类型 |
|---|---|---|
5 + 2 |
7 |
int |
5 + 2.0 |
7.0 |
float |
5 / 2 |
2.5 |
float |
4 / 2 |
2.0 |
float |
5 // 2 |
2 |
int |
5 % 2 |
1 |
int |
2 ** 3 |
8 |
int |
/ 是普通除法,结果通常为 float;// 是向下取整除法;% 取余数;** 表示幂。
运算优先级与数学类似:括号 → 幂 → 乘除 → 加减。业务公式建议主动加括号:
net_sales = (sales_quantity - return_quantity) * unit_price
十一、比较运算与边界值¶
| 运算符 | 含义 | 示例 |
|---|---|---|
> |
大于 | quantity > 100 |
>= |
大于等于 | quantity >= 100 |
< |
小于 | price < 50 |
<= |
小于等于 | age <= 30 |
== |
等于 | gender == "女" |
!= |
不等于 | returns != 0 |
科图题干中的“销售数量在 100 以上”需要特别确认评分口径:
- 严格大于 100:
> 100 - 包含 100:
>= 100
测试 99、100、101 可以检查边界是否写对。
Python 支持连续比较:
60 <= age <= 69
等价于“年龄大于等于 60,并且小于等于 69”。
比较值是否相等使用 ==;is 检查是否为同一个对象,初学阶段主要把 is 用于
value is None,不要用 is 代替普通数值或字符串的 ==。
十二、数字与数字文本不能混用¶
quantity_number = 125
quantity_text = "125"
print(type(quantity_number))
print(type(quantity_text))
<class 'int'> <class 'str'>
屏幕上都能看到 125,但类型不同:
125可以直接参与数值运算;"125"是文本,需要先转换;- 网页和 CSV 中的数值字段经常被读取成字符串;
- pandas 阶段会使用
astype()或pd.to_numeric()。
数字文本按字符顺序比较,而不是按数值大小比较:
"9" > "100" # True,因为先比较字符 "9" 和 "1"
9 > 100 # False
Python 3 不允许直接比较文本和数值的大小:"9" > 100 会触发 TypeError。
排序、筛选和统计前必须先确认类型。
十三、布尔值 bool¶
布尔值只有 True 和 False。最常见来源是比较表达式:
quantity > 100
gender == "女"
return_quantity != 0
不要把布尔值写成字符串:
is_valid = True # 布尔值
is_valid = "True" # 普通文本
True、False 首字母必须大写;true 和 false 会被当成未定义变量。
真题中的布尔值¶
- 名仕:
hasNextPage控制分页循环; - 科图:
x == "女"生成布尔序列,布尔均值可以计算女性占比; - 青娅:
df["项目"].isin([...])生成布尔筛选条件; - 通用:多个条件可以组合成最终筛选结果。
布尔值不是文字 "True",也不是随意填写的标签,而是比较或逻辑运算的结果。
十四、逻辑运算:and、or、not¶
| 运算 | 含义 | 示例 |
|---|---|---|
and |
两个条件都成立 | quantity >= 100 and price < 200 |
or |
至少一个条件成立 | city == "北京" or city == "上海" |
not |
对结果取反 | not has_next_page |
示例:
quantity = 125
price = 199.0
is_target = (quantity >= 100) and (price < 200)
print(is_target) # True
优先级大致为:算术运算 → 比较运算 → not → and → or。
多条件业务规则应主动使用括号,让评分者和自己都能看清条件分组。
Python 使用短路计算:
A and B中,如果 A 已经为假,B 不再执行;A or B中,如果 A 已经为真,B 不再执行。
可以先检查分母不为零,再计算比例:
has_valid_rate = (sales_quantity != 0) and (
return_quantity / sales_quantity < 0.10
)
注意 pandas 布尔筛选使用 &、|、~,并要求每个条件加括号;不能直接照搬普通 Python 的
and、or。这一点会在 pandas 专题中详细学习。
quantity = 125
price = 199.0
has_stock = True
condition_a = quantity >= 100
condition_b = price < 200
is_target = condition_a and condition_b and has_stock
print("数量达标:", condition_a)
print("价格达标:", condition_b)
print("最终筛选结果:", is_target)
数量达标: True 价格达标: True 最终筛选结果: True
十五、真值与 bool() 的易错点¶
在需要逻辑判断的位置,以下值通常视为 False:
- 数值零:
0、0.0 - 空字符串:
"" - 空列表、空字典:
[]、{} None- 布尔值
False
其他大多数非空值视为 True。尤其注意:
bool("False") # True,因为它是非空字符串
bool("0") # True,因为它是非空字符串
bool(0) # False
因此网页或 CSV 中的 "False" 不能直接通过 bool(text) 转成正确布尔值,
应先清洗文本并明确映射。
and、or 作用于原始值时可能返回某个原始操作数,而不一定返回严格的 True/False。
初学和竞赛筛选代码应优先让两侧都是清晰的比较表达式。
十六、None 表示“没有值”¶
coupon_code = None
None 不等于:
- 数字
0 - 空字符串
"" - 布尔值
False - 字符串
"None"
推荐判断方法:
if coupon_code is None:
print("没有优惠码")
None 常见于函数没有返回有效结果、字典字段不存在或接口返回空值。
pandas 中还会遇到 NaN、NaT、pd.NA;它们与 None 有联系但并不完全相同,
后续应使用 isna()/notna() 统一检查缺失值。
十七、Python 类型与 pandas 列类型¶
Python 单个值常见类型:
str / int / float / bool / NoneType
pandas 一整列常见类型:
object 或 string / int64 / float64 / bool / datetime64
读取 CSV 后要先检查:
print(df.dtypes)
df.info()
需要注意:
- 某列混有数字和文字时,可能被推断为
object; - 整数列出现普通缺失值后,可能变成
float64; "1,299"、"¥199"、"25%"都不是可直接计算的纯数值;"2026-07-22"默认可能仍是字符串,而不是日期;- 布尔筛选前必须确认条件结果和索引对齐。
真题中不能只看表格显示内容,要同时检查列类型和缺失情况。
十八、常见报错与原因¶
| 错误或现象 | 原因 | 修复方向 |
|---|---|---|
NameError |
文本漏引号、名称拼错、变量尚未赋值 | 检查报错名称和执行顺序 |
SyntaxError |
非法变量名、比较中误写 =、中文符号 |
检查当前行及上一行 |
TypeError |
不兼容类型参与运算 | 使用 type() 检查两侧 |
ZeroDivisionError |
比率计算时分母为零 | 除法前检查分母或使用短路条件 |
"12" + "3" 得到 "123" |
两侧都是字符串 | 转为数值后再计算 |
0.1 + 0.2 != 0.3 |
二进制浮点近似 | 使用 isclose、舍入或 Decimal |
bool("False") 得到 True |
非空字符串真值为真 | 显式映射文本 |
type(...) 突然不能调用 |
覆盖了内置名称 type |
重命名并重启内核 |
| 边界样本少一行 | > 与 >= 口径错误 |
用边界前、边界、边界后测试 |
报错时先打印值和类型:
print("quantity =", repr(quantity))
print("type =", type(quantity))
repr() 会把字符串引号、换行符等细节显示出来,比普通 print() 更适合排查脏数据。
十九、真题中的类型检查清单¶
每个关键字段至少确认:
| 问题 | 示例 | |
|---|---|---|
| 当前值是什么 | repr(value) |
|
| Python 类型是什么 | type(value) |
|
| 是否缺失 | value is None 或 pandas isna() |
|
| 数字是否仍是文本 | "125"、"1,299"、"25%" |
|
| 边界是否包含等号 | > 100 还是 >= 100 |
|
| 多条件如何组合 | and/or 或 pandas `&/ |
` |
| 浮点结果如何比较 | isclose() 或业务舍入规则 |
|
| 是否覆盖内置名称 | str、list、sum、type |
针对性练习¶
使用 学生练习.py 完成变量命名、五类值、类型检查、数值与数字文本、浮点精度、
边界值、逻辑组合、None 和错误诊断练习。每个实验先预测,再运行并解释结果。