Module 4: Python 数据结构
组织数据的艺术 —— 列表、字典、元组、集合
本章概览
如果说变量是存储单个数据的容器,那么数据结构就是组织多个数据的方式。本章将介绍 Python 的四种核心数据结构:列表(List)、元组(Tuple)、字典(Dictionary)、集合(Set)。掌握它们,你就能高效处理复杂的研究数据。
学习目标
学完本章后,你将能够:
- 理解四种数据结构的特点和使用场景
- 熟练操作列表(增删改查、切片、排序)
- 使用字典存储键值对数据
- 理解元组的不可变性和应用
- 使用集合进行去重和集合运算
- 选择合适的数据结构解决实际问题
- 对比 Python 与 Stata/R 的数据组织方式
章节内容
01 - 列表 (Lists)
核心问题: 如何存储和操作有序的数据集合?
核心内容:
- 列表创建:
[],list(),range() - 索引访问(正向/负向)
- 切片操作:
list[start:end:step] - 列表方法:
- 添加:
append(),insert(),extend() - 删除:
remove(),pop(),clear() - 排序:
sort(),sorted(),reverse() - 查找:
index(),count(),in
- 添加:
- 列表推导式(进阶语法)
- 嵌套列表(二维数据)
- 对比 R 的 vector 和 Stata 的变量
实际应用:
# 存储多个学生的成绩
grades = [85, 92, 78, 95, 88]
# 筛选及格成绩
passed = [g for g in grades if g >= 60]
# 计算平均分
avg_grade = sum(grades) / len(grades)
# 找出最高分和最低分
max_grade = max(grades)
min_grade = min(grades)研究场景:
- 存储样本数据(年龄、收入、教育年限)
- 批量处理变量名
- 存储回归系数
- 时间序列数据
02 - 元组 (Tuples)
核心问题: 什么时候需要不可变的数据结构?
核心内容:
- 元组创建:
(),tuple() - 不可变性(immutable)的意义
- 元组解包(unpacking)
- 单元素元组的陷阱:
(1,)vs(1) - 元组 vs 列表:何时用哪个?
- 命名元组(
namedtuple)
实际应用:
# 存储固定配置(不应被修改)
regression_params = ("OLS", 0.05, 1000) # 模型类型、显著性水平、样本量
# 函数返回多个值
def calculate_stats(data):
return (mean(data), median(data), std(data))
mean_val, median_val, std_val = calculate_stats(incomes)
# 字典的键(必须不可变)
results = {
("Model1", "OLS"): 0.85,
("Model2", "Logit"): 0.78
}何时使用元组?
- 数据不应被修改(配置参数、常量)
- 作为字典的键
- 函数返回多个值
- 性能要求高(元组比列表快)
03 - 字典 (Dictionaries)
核心问题: 如何存储键值对应的数据?
核心内容:
- 字典创建:
{},dict(), 字典推导式 - 访问和修改:
dict[key],dict.get(key, default) - 字典方法:
- 键/值/项:
keys(),values(),items() - 更新:
update(),setdefault() - 删除:
pop(),del,clear()
- 键/值/项:
- 嵌套字典(多层数据)
- 字典遍历
- 对比 R 的 named list
实际应用:
# 存储个人信息
student = {
"name": "Alice",
"age": 22,
"major": "Economics",
"gpa": 3.8
}
# 存储回归结果
regression_results = {
"Model1": {"coef": 0.45, "se": 0.12, "r2": 0.65},
"Model2": {"coef": 0.52, "se": 0.10, "r2": 0.72}
}
# 变量映射
var_labels = {
"edu": "受教育年限",
"income": "年收入",
"age": "年龄"
}研究场景:
- 存储个体属性(ID → 属性值)
- 回归结果整理
- 变量名映射和标签
- 配置文件(参数设置)
04 - 集合 (Sets)
核心问题: 如何处理唯一值和集合运算?
核心内容:
- 集合创建:
{},set() - 集合特点:无序、唯一、可变
- 集合操作:
- 添加/删除:
add(),remove(),discard() - 集合运算:并集(
|)、交集(&)、差集(-)、对称差(^) - 子集判断:
issubset(),issuperset()
- 添加/删除:
- 去重操作
- 成员检测(效率高)
实际应用:
# 数据去重
all_ids = [101, 102, 103, 101, 104, 102]
unique_ids = set(all_ids) # {101, 102, 103, 104}
# 找出两组受访者的交集
group_a = {101, 102, 103, 104}
group_b = {103, 104, 105, 106}
both_groups = group_a & group_b # {103, 104}
# 快速检查成员资格(比列表快)
if 101 in unique_ids:
print("ID 101 存在")研究场景:
- 数据去重
- 样本匹配(交集)
- 差异分析(差集)
- ID 查重
05 - 小结和复习
内容:
- 四种数据结构对比表
- 选择决策树
- 综合练习题
- 性能对比
- 常见错误和最佳实践
四种数据结构对比
| 特性 | 列表(List) | 元组(Tuple) | 字典(Dict) | 集合(Set) |
|---|---|---|---|---|
| 符号 | [...] | (...) | {k:v, ...} | {...} |
| 有序 | (3.7+保持插入顺序) | |||
| 可变 | ||||
| 重复 | 键唯一,值可重复 | |||
| 索引 | 整数索引 | 整数索引 | 键索引 | 无索引 |
| 典型用途 | 有序集合 | 不可变集合 | 键值映射 | 唯一值、集合运算 |
选择指南
什么时候用列表?
- 需要存储有序的元素(成绩、年份、价格)
- 需要修改数据(添加、删除、排序)
- 需要通过索引访问
什么时候用元组?
- 数据不应被修改(配置、常量)
- 作为字典的键
- 函数返回多个值
- 性能优先(比列表快)
什么时候用字典?
- 需要通过名称/ID 查找数据
- 存储属性(人名 → 属性)
- 计数、映射、查找表
什么时候用集合?
- 需要去重
- 需要集合运算(交/并/差)
- 快速成员检测
如何学习本章?
学习路线
第 1 天(3小时): 列表
- 阅读 01 - 列表
- 练习索引、切片、方法
- 编写列表推导式
第 2 天(2小时): 元组
- 阅读 02 - 元组
- 理解不可变性
- 练习元组解包
第 3 天(3小时): 字典
- 阅读 03 - 字典
- 创建嵌套字典
- 练习字典遍历和方法
第 4 天(2小时): 集合
- 阅读 04 - 集合
- 练习集合运算
- 数据去重实践
第 5 天(2小时): 复习和综合应用
- 完成 05 - 小结和复习
- 综合练习题
- 对比四种结构
总时间: 12 小时(1-2 周)
最小化学习路径
如果时间有限:
必学(核心结构,8小时):
- 01 - 列表(完整学习)
- 03 - 字典(完整学习)
- 02 - 元组(基础部分)
- 04 - 集合(去重操作)
选学(进阶技巧):
- 列表推导式
- 嵌套字典
- 集合运算
- 命名元组
学习建议
从应用场景出发
- 思考:"我的研究数据适合哪种结构?"
- 将 Stata/R 的数据组织方式对应到 Python
- 用实际数据练习
对比学习
python# 列表:有序、可变 grades = [85, 92, 78] grades.append(95) # 可以修改 # 元组:有序、不可变 config = (85, 92, 78) # config.append(95) # 错误!不能修改 # 字典:键值对 student = {"name": "Alice", "grade": 85} # 集合:唯一值 unique_grades = {85, 92, 78, 85} # {85, 92, 78}性能意识
- 列表查找:
O(n)—— 慢 - 字典/集合查找:
O(1)—— 快 - 大数据量时选择合适的结构
- 列表查找:
避免常见错误
- 不要混淆
[](列表)、()(元组)、{}(字典/集合) - 记住列表索引从 0 开始
- 字典访问不存在的键会报错,用
get()更安全
- 不要混淆
常见问题
Q: 为什么有这么多数据结构?直接用列表不行吗? A: 不同结构有不同优势。列表适合有序数据,字典适合查找,集合适合去重。选对结构能让代码更高效、更易读。
Q: Python 的字典对应 Stata/R 的什么? A:
- Stata 没有直接对应物(最接近的是 value labels)
- R 的 named list 类似字典
Q: 什么时候用列表推导式? A: 当你需要用循环创建列表时,推导式更简洁。但如果逻辑复杂,还是用普通循环更清晰。
Q: 集合和列表去重有什么区别? A: set(list) 是最快的去重方法,但会丢失顺序。如果需要保持顺序,用 list(dict.fromkeys(list))。
Q: 为什么字典的键必须是不可变类型? A: 因为字典用哈希表实现,键必须是可哈希的(不可变)。所以可以用元组,不能用列表。
下一步
完成本章后,你将掌握:
- Python 的四种核心数据结构
- 如何选择合适的结构组织数据
- 高效的数据操作方法
在 Module 5 中,我们将学习函数和模块,让代码更加模块化和可复用。
在 Module 6-7 中,我们将学习 Pandas,它将列表、字典等结构整合成强大的 DataFrame!
继续前进!掌握数据结构,你离真正的数据分析只差一步了!