Skip to content

第 05 章 · 数据结构:列表、元组、字典、集合 ​

本章目标 ​

掌握四种最常用的"装数据的盒子",会用它们解决 80% 的日常问题。

类型写法特点典型用途
列表 list[1, 2, 3]有序、可变、可重复一堆同类数据
元组 tuple(1, 2, 3)有序、不可变不会改的一组值(坐标)
字典 dict{"a": 1}键值对、查找快有名字的数据(配置、记录)
集合 set{1, 2, 3}无序、不重复去重、判断是否存在

5.1 列表 list ​

增删改查 ​

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

# 查
print(fruits[0])          # 苹果
print(fruits[-1])         # 橘子
print(fruits[0:2])        # ['苹果', '香蕉']
print(len(fruits))        # 3

# 改
fruits[1] = "葡萄"
print(fruits)             # ['苹果', '葡萄', '橘子']

# 增
fruits.append("桃子")         # 末尾加一个
fruits.insert(0, "西瓜")      # 指定位置插入
fruits.extend(["梨", "杏"])   # 批量追加

# 删
fruits.remove("葡萄")     # 按值删(不存在会报错)
last = fruits.pop()       # 弹出最后一个并返回
del fruits[0]             # 按下标删
fruits.clear()            # 清空

排序与查找 ​

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

nums.sort()                    # 原地排序(改变自己)
print(nums)                    # [1, 1, 3, 4, 5]

sorted_nums = sorted(nums, reverse=True)   # 生成新列表
print(sorted_nums)             # [5, 4, 3, 1, 1]

print(1 in nums)               # True
print(nums.count(1))           # 2
print(nums.index(3))           # 2

sort() 和 sorted() 的区别:前者改原列表,后者返回新列表。老手都容易写错。

列表推导式(重点,写起来很爽) ​

python
nums = [1, 2, 3, 4, 5, 6]

squares = [n * n for n in nums]
print(squares)                        # [1, 4, 9, 16, 25, 36]

evens = [n for n in nums if n % 2 == 0]
print(evens)                          # [2, 4, 6]

一句话理解:[对每一项做什么 for 每一项 in 原数据 if 满足条件]。

嵌套也能用(了解即可):

python
matrix = [[1, 2], [3, 4]]
flat = [x for row in matrix for x in row]
print(flat)          # [1, 2, 3, 4]

常用模式:堆栈 / 队列 ​

python
stack = []
stack.append(1)      # 进
stack.append(2)
stack.pop()          # 出:2(后进先出)

from collections import deque
queue = deque(["a", "b"])
queue.append("c")    # 从右边进
queue.popleft()      # 从左边出:'a'(先进先出)

列表做队列时 pop(0) 很慢,数据多就用 deque。

5.2 元组 tuple ​

python
point = (3, 5)
x, y = point           # 解包
print(x, y)            # 3 5

# point[0] = 9         # ❌ TypeError:元组不可变

元组当"不会变的记录"最合适:坐标、RGB 颜色、数据库一行。不可变意味着安全——传给别人也不用担心被改。

单元素元组要加逗号:(1,),写成 (1) 就只是数字 1。

5.3 字典 dict(最常用的结构之一) ​

python
user = {"name": "小明", "age": 18, "city": "鄂尔多斯"}

# 查
print(user["name"])            # 小明
print(user.get("phone"))       # None   ← 键不存在也不报错
print(user.get("phone", "未填"))# 未填   ← 给默认值

# 改 / 增
user["age"] = 19               # 已存在就改
user["phone"] = "138xxxx"      # 不存在就新增

# 删
del user["city"]
phone = user.pop("phone", None)

# 遍历
for key, value in user.items():
    print(key, "=", value)

print(list(user.keys()))       # ['name', 'age']
print("name" in user)          # True    ← 判断的是"键"

⚠️ user["不存在的键"] 会报 KeyError,不确定时用 .get()。

字典推导式 ​

python
squares = {n: n * n for n in range(1, 5)}
print(squares)     # {1: 1, 2: 4, 3: 9, 4: 16}

字典的典型用途:计数 ​

python
text = "apple banana apple cherry apple"
counter = {}
for word in text.split():
    counter[word] = counter.get(word, 0) + 1
print(counter)     # {'apple': 3, 'banana': 1, 'cherry': 1}

5.4 集合 set ​

python
a = {1, 2, 3}
b = {3, 4}

print(a | b)     # {1, 2, 3, 4}  并集
print(a & b)     # {3}           交集
print(a - b)     # {1, 2}        差集

nums = [1, 2, 2, 3, 3, 3]
print(list(set(nums)))    # [1, 2, 3]   ← 去重最常见用法
print(2 in a)             # True        ← 判断存在,比列表快得多

⚠️ 集合是无序的,不能按下标取;空集合要写 set(),{} 是空字典。

5.5 循环的实用技巧 ​

python
names = ["小明", "小红", "小刚"]

# 同时拿下标和值
for i, name in enumerate(names, start=1):
    print(i, name)

# 同时遍历两个列表
ages = [18, 19, 20]
for name, age in zip(names, ages):
    print(name, age)

# 倒着遍历
for name in reversed(names):
    print(name)

5.6 深浅复制(踩坑重灾区) ​

python
a = [1, 2, 3]
b = a              # b 和 a 是同一个列表!
b.append(4)
print(a)           # [1, 2, 3, 4]  ← a 也变了

c = a.copy()       # 浅拷贝:新列表
c.append(5)
print(a)           # [1, 2, 3, 4]  ← 对扁平列表,a 不受影响 ✅

但列表里套列表时,浅拷贝就不够用了:

python
x = [[1, 2], [3, 4]]
y = x.copy()            # 浅拷贝:只复制最外层

y[0].append(9)          # 修改内层那个小列表
print(x)                # [[1, 2, 9], [3, 4]]  ← x 也变了!

y.append([5, 6])        # 增删最外层
print(x)                # [[1, 2, 9], [3, 4]]  ← 这个不影响 ✅

原因:浅拷贝只复制了"外层那一排门牌号",内外层指向的还是同一些内层列表。要彻底断开,用深拷贝:

python
import copy
x = [[1, 2], [3, 4]]
z = copy.deepcopy(x)
z[0].append(9)
print(x)                 # [[1, 2], [3, 4]]  ← x 毫发无伤 ✅

三句话记住:

  • = 只是起了个别名,两个名字指同一个列表
  • .copy() 只复制最外层,嵌套对象仍是共享的
  • copy.deepcopy() 才是彻底切断(数据小的时候放心用,数据特别大时慢一些)

5.7 比较与条件小技巧 ​

python
print([1, 2] == [1, 2])          # True   逐项比较
print([1, 2] < [1, 3])           # True   按顺序比大小

age = 25
result = "成年" if age >= 18 else "未成年"    # 三元表达式

if 18 <= age < 60:               # 链式比较
    print("劳动年龄")

5.8 练一练 ​

  1. 有一个成绩列表 [88, 92, 79, 100, 65],输出平均分、最高分、最低分,并列出所有及格(≥60)的成绩。
  2. 统计一段文字里每个字出现的次数,输出出现最多的 3 个(提示:字典 + sorted)。
  3. 有两个列表 [1,2,3,4] 和 [3,4,5,6],求交集、并集、只在第一个里出现的元素。
  4. 用列表推导式生成 1–100 中所有能被 7 整除的数。

本章关键词 ​

列表 append / pop / sort、推导式、元组解包、字典 get / items、集合去重、enumerate / zip、深浅拷贝

试图用自己的方式,重新定义属于我的人生