Skip to content

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 的变量

实际应用:

python
# 存储多个学生的成绩
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)

实际应用:

python
# 存储固定配置(不应被修改)
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

实际应用:

python
# 存储个人信息
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()
  • 去重操作
  • 成员检测(效率高)

实际应用:

python
# 数据去重
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 - 集合(去重操作)

选学(进阶技巧):

  • 列表推导式
  • 嵌套字典
  • 集合运算
  • 命名元组

学习建议

  1. 从应用场景出发

    • 思考:"我的研究数据适合哪种结构?"
    • 将 Stata/R 的数据组织方式对应到 Python
    • 用实际数据练习
  2. 对比学习

    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}
  3. 性能意识

    • 列表查找:O(n) —— 慢
    • 字典/集合查找:O(1) —— 快
    • 大数据量时选择合适的结构
  4. 避免常见错误

    • 不要混淆 [](列表)、()(元组)、{}(字典/集合)
    • 记住列表索引从 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!

继续前进!掌握数据结构,你离真正的数据分析只差一步了!


快速链接

基于 MIT 许可证发布。内容版权归作者所有。