Skip to content

04 数据结构

📋 资料说明

  • 来源:课程 day03~day04
  • 笔记尚硅谷大模型技术之Python1.0.docx 第 5 章"数据结构"
  • 每日一考day03_每日一考.mdday04_每日一考.md
  • 视频:❌ 跳过(约 24 个视频:列表 → 字符串 → 元组 → 集合 → 字典)

🟢 🤖 AI 替代率:98%

为什么是这个水平:

Python 内建数据结构的 API(增删改查方法)是确定性知识。AI 对 list.append()dict.get()set.union() 等方法的参数、返回值和副作用的描述准确率极高。唯一的 2% 不确定性在于:深拷贝/浅拷贝涉及的内存模型理解——但这一对比差异已在函数章节中讨论。


👤 人工干预率:2%

极低。建议了解不同数据结构的选型原则(什么场景用列表、什么场景用字典、什么时候用集合),这在实际项目中比记住所有 API 更重要。AI 可以帮你写代码,但你要告诉 AI 用什么数据结构。


1. 列表 (list)

Python 列表是可变、有序、可重复的序列。

创建与访问

python
# 创建
empty = []
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]
nested = [[1, 2], [3, 4]]   # 嵌套列表

# 索引(从 0 开始)
print(numbers[0])       # 1
print(numbers[-1])      # 5 (负数索引从右开始)
print(numbers[-2])      # 4

# 切片 [start:stop:step]
print(numbers[1:3])     # [2, 3]
print(numbers[:3])      # [1, 2, 3]
print(numbers[::2])     # [1, 3, 5]
print(numbers[::-1])    # [5, 4, 3, 2, 1](反转)

常用操作

python
fruits = ["苹果", "香蕉"]

# 增
fruits.append("橘子")           # 末尾添加
fruits.insert(1, "葡萄")        # 指定位置插入
fruits.extend(["西瓜", "芒果"]) # 合并列表

# 删
fruits.remove("香蕉")           # 删除指定元素(第一个匹配项)
popped = fruits.pop()           # 删除并返回最后一个
popped = fruits.pop(1)          # 删除并返回索引为 1 的元素
fruits.clear()                  # 清空所有元素

# 改
fruits[0] = "草莓"              # 修改指定位置元素

# 查
print("苹果" in fruits)         # True(成员判断)
print(fruits.index("香蕉"))     # 查找索引(不存在抛出 ValueError)
print(fruits.count("苹果"))     # 统计出现次数

列表排序

python
numbers = [3, 1, 4, 1, 5, 9, 2]

# 原地排序(修改原列表)
numbers.sort()          # [1, 1, 2, 3, 4, 5, 9]
numbers.sort(reverse=True)  # [9, 5, 4, 3, 2, 1, 1]

# 返回新列表
sorted_numbers = sorted(numbers)

# 自定义排序
words = ["banana", "apple", "cherry"]
words.sort(key=len)     # 按字符串长度排序

列表推导式

python
# [表达式 for 变量 in 可迭代对象 if 条件]

# 基本
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 带条件
evens = [x for x in range(20) if x % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 嵌套循环
pairs = [(x, y) for x in [1, 2] for y in [3, 4]]
# [(1, 3), (1, 4), (2, 3), (2, 4)]

# 条件表达式
labels = ["偶数" if x % 2 == 0 else "奇数" for x in range(5)]
# ['偶数', '奇数', '偶数', '奇数', '偶数']

常用函数

python
numbers = [3, 1, 4, 1, 5]

print(len(numbers))     # 5(长度)
print(sum(numbers))     # 14(总和)
print(max(numbers))     # 5(最大值)
print(min(numbers))     # 1(最小值)

2. 字符串 (str)

字符串是不可变序列。

常用操作

python
s = "Hello, Python World"

# 大小写
print(s.upper())              # HELLO, PYTHON WORLD
print(s.lower())              # hello, python world
print(s.capitalize())         # Hello, python world
print(s.title())              # Hello, Python World

# 查找
print(s.find("Python"))       # 7(索引位置,-1 表示未找到)
print(s.index("Python"))      # 7(不存在抛出 ValueError)
print(s.count("o"))           # 3(出现次数)
print(s.startswith("Hello"))  # True
print(s.endswith("World"))    # True

# 替换
print(s.replace("Python", "Java"))  # Hello, Java World

# 分割与连接
words = s.split()                   # ['Hello,', 'Python', 'World']
print(words)
print(", ".join(words))             # Hello,, Python, World

# 去除空白
s2 = "  hello  "
print(s2.strip())           # "hello"
print(s2.lstrip())          # "hello  "
print(s2.rstrip())          # "  hello"

# 判断
print("123".isdigit())      # True
print("abc".isalpha())      # True
print("abc123".isalnum())   # True

# 字符串格式化(详见 02 章)
name = "Alice"
age = 25
print(f"{name} is {age} years old")

注意事项: 字符串是不可变对象,所有"修改"操作都返回新字符串,原字符串不变。


3. 元组 (tuple)

元组是不可变、有序、可重复的序列。

python
# 创建
empty = ()
single = (1,)       # 注意逗号,不加逗号是整数
numbers = (1, 2, 3, 4, 5)
mixed = (1, "hello", 3.14)

# 访问(与列表相同)
print(numbers[0])       # 1
print(numbers[1:3])     # (2, 3)

# 元组是不可变的,不能修改元素
# numbers[0] = 10       # ❌ TypeError

# 元组解包
a, b, c = (1, 2, 3)
print(a, b, c)          # 1 2 3

# 交换变量(本质是元组解包)
x, y = 10, 20
x, y = y, x
print(x, y)             # 20 10

什么时候用元组?

  • 数据不应被修改(如坐标、数据库记录)
  • 作为字典的键(列表不能做键)
  • 函数返回多个值(实际上返回的就是元组)

4. 集合 (set)

集合是可变、无序、不重复的元素集合。

python
# 创建
empty = set()           # 注意:{} 是空字典
numbers = {1, 2, 3, 3, 2, 1}   # {1, 2, 3}(自动去重)
from_list = set([1, 2, 3, 3])  # {1, 2, 3}

# 增
numbers.add(4)
numbers.update([5, 6, 7])   # 批量添加

# 删
numbers.remove(3)           # 删除指定元素(不存在抛出 KeyError)
numbers.discard(3)          # 删除指定元素(不存在不报错)
numbers.pop()               # 随机删除并返回一个元素
numbers.clear()             # 清空

# 集合运算
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

print(a | b)    # 并集: {1, 2, 3, 4, 5, 6}
print(a & b)    # 交集: {3, 4}
print(a - b)    # 差集: {1, 2}
print(a ^ b)    # 对称差: {1, 2, 5, 6}

# 判断
print(1 in a)           # True
print(a.issubset(b))    # False(a 是否是 b 的子集)

什么时候用集合?

  • 去重
  • 快速成员检查(in 操作时间复杂度 O(1),列表是 O(n))
  • 数学集合运算

5. 字典 (dict)

字典是键值对的无序集合(Python 3.7+ 保持插入顺序)。

python
# 创建
empty = {}
student = {
    "name": "Alice",
    "age": 25,
    "scores": [90, 85, 92]
}

# 访问
print(student["name"])      # Alice(键不存在抛出 KeyError)
print(student.get("name"))  # Alice(键不存在返回 None)
print(student.get("gender", "未知"))  # "未知"(指定默认值)

# 增/改
student["gender"] = "女"         # 键不存在则新增
student["age"] = 26              # 键存在则修改
student.update({"phone": "123", "email": "a@b.com"})  # 批量更新

# 删
del student["phone"]             # 删除指定键
age = student.pop("age")         # 删除并返回对应值
student.clear()                  # 清空

# 遍历
for key in student:
    print(key, student[key])

for key, value in student.items():
    print(key, value)

for key in student.keys():
    print(key)

for value in student.values():
    print(value)

# 字典推导式
squares = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 4}

键的要求:键必须是不可变类型(字符串、数字、元组)。列表和字典不能做键。

defaultdict 和 Counter

python
from collections import defaultdict, Counter

# defaultdict:键不存在时自动创建默认值
word_count = defaultdict(int)
for word in ["a", "b", "a", "c", "b", "a"]:
    word_count[word] += 1
print(dict(word_count))  # {'a': 3, 'b': 2, 'c': 1}

# Counter:计数更简单
counter = Counter(["a", "b", "a", "c", "b", "a"])
print(counter)           # Counter({'a': 3, 'b': 2, 'c': 1})
print(counter.most_common(2))  # [('a', 3), ('b', 2)]

数据结构选型指南

场景推荐结构原因
有序存储、可重复列表最通用的序列
需要快速去重集合O(1) 查找
键值对映射字典通过键快速取值
只读数据、可哈希元组不可变、可作字典键
文本处理字符串丰富的 API

6. 练习题

练习 1:列表操作

现有列表 my_list = [10, 20, 30, 40, 50]

  1. 向末尾添加 60
  2. 取出索引为 2 的元素
  3. 计算所有元素的和

练习 2:字典操作

既有学生成绩字典:

python
students = {
    "Alice": {"Math": 85, "English": 90, "Science": 78},
    "Bob": {"Math": 92, "English": 88, "Science": 95},
    "Charlie": {"Math": 70, "English": 75, "Science": 80}
}

计算每个学生的平均分。

练习 3:去重

给定 [1, 2, 2, 3, 4, 3, 5],去重后排序输出。

练习 4:列表推导式

使用推导式生成 1~100 中所有能被 3 或 5 整除的数字。


参考答案

练习 1:

python
my_list = [10, 20, 30, 40, 50]
my_list.append(60)
element = my_list[2]
total = sum(my_list)
print(element, total)  # 30 210

练习 2:

python
for name, scores in students.items():
    avg = sum(scores.values()) / len(scores)
    print(f"{name}: {avg:.1f}")
# Alice: 84.3, Bob: 91.7, Charlie: 75.0

练习 3:

python
nums = [1, 2, 2, 3, 4, 3, 5]
print(sorted(set(nums)))  # [1, 2, 3, 4, 5]

练习 4:

python
result = [x for x in range(1, 101) if x % 3 == 0 or x % 5 == 0]
print(result[:20])  # 前 20 个

OPC 超级个体实战指南