从“数据容器“的角度,彻底掌握 Python 五大核心数据结构
一、数据结构全景图
1.1 一句话认识五大结构
# 如果把数据比作"物品",数据结构就是不同的"收纳方式" str = "hello" # 字符的排列(像一串珠子) list = [1, 2, 3] # 有序的箱子(可以随意增删改) tuple = (1, 2, 3) # 封存的盒子(创建后不能改变) dict = {"name": "张三"} # 带标签的抽屉(通过标签找东西) set = {1, 2, 3} # 独一无二的收藏柜(自动去重)1.2 核心特性速查表
| 特性 | str | list | tuple | dict | set |
|---|---|---|---|---|---|
| 是否有序 | 有序 | 有序 | 有序 | 有序(3.7+) | 无序 |
| 是否可变 | 不可变 | 可变 | 不可变 | 可变 | 可变 |
| 是否允许重复 | - | 允许 | 允许 | 键唯一 | 元素唯一 |
| 访问方式 | 整数索引 | 整数索引 | 整数索引 | 键(key) | 无索引 |
| 元素类型限制 | 字符 | 任意 | 任意 | 键不可变 | 元素不可变 |
| 创建符号 | " " | [ ] | ( ) | { } | { } |
| 典型场景 | 文本处理 | 动态序列 | 不可变序列 | 键值映射 | 去重/集合运算 |
二、字符串(str)—— 文本的容器
2.1 本质与特性
字符串是不可变的字符序列,每个字符就像项链上的一颗珠子,一旦串好就不能改变。
# 创建方式 s1 = 'hello' # 单引号 s2 = "world" # 双引号 s3 = """多行 字符串""" # 三引号 s4 = str(123) # 类型转换 → "123" # 核心特性:不可变 s = "hello" # s[0] = "H" # TypeError: 'str' object does not support item assignment s = "H" + s[1:] # 创建新字符串 "Hello"2.2 常用方法速查
s = " Hello World " # 大小写转换 s.upper() # " HELLO WORLD " s.lower() # " hello world " s.capitalize() # " hello world " s.title() # " Hello World " # 去除空白 s.strip() # "Hello World" s.lstrip() # "Hello World " s.rstrip() # " Hello World" # 查找与判断 s.find("World") # 8(返回索引,不存在返回 -1) s.index("World") # 8(不存在抛出 ValueError) s.startswith(" ") # True s.endswith("ld ") # True "123".isdigit() # True "abc".isalpha() # True # 分割与拼接 s.split() # ['Hello', 'World'] "a,b,c".split(",") # ['a', 'b', 'c'] "-".join(["a","b"]) # "a-b" # 替换 s.replace("World", "Python") # " Hello Python "2.3 常用场景
# 1. 用户输入清洗 username = input("请输入用户名:").strip().lower() # 2. 格式化输出 name = "张三" age = 25 print(f"姓名:{name},年龄:{age}") # 3. 字符串拼接(大量拼接用 join) result = "-".join(["2026", "07", "21"]) # "2026-07-21" # 4. 字符串切片 text = "Python" text[::-1] # "nohtyP"(反转) text[1:4] # "yth"2.4 记忆要点
字符串是不可变的字符序列,所有"修改"操作实际上都是创建新字符串。
三、列表(list)—— 动态的容器
3.1 本质与特性
列表是可变的有序序列,像一个可以随时增减物品的购物车。
# 创建方式 lst1 = [] # 空列表 lst2 = [1, 2, 3] # 直接创建 lst3 = list("hello") # ['h','e','l','l','o'] lst4 = [x*2 for x in range(5)] # [0,2,4,6,8] 列表推导式 # 核心特性:可变 lst = [1, 2, 3] lst[0] = 100 # 修改 lst.append(4) # 添加 lst.pop() # 删除3.2 常用方法速查
| 方法 | 说明 | 示例 |
|---|---|---|
append(x) | 末尾添加一个元素 | lst.append(4) |
extend(iterable) | 末尾添加多个元素 | lst.extend([4,5]) |
insert(i, x) | 指定位置插入 | lst.insert(0, 0) |
remove(x) | 删除第一个匹配项 | lst.remove(2) |
pop(i) | 删除并返回指定位置元素 | lst.pop(0) |
clear() | 清空列表 | lst.clear() |
index(x) | 返回第一个匹配项索引 | lst.index(3) |
count(x) | 统计元素出现次数 | lst.count(2) |
sort() | 原地排序 | lst.sort() |
reverse() | 原地反转 | lst.reverse() |
copy() | 浅拷贝 | lst2 = lst.copy() |
3.3 常用场景
# 1. 数据收集与遍历 students = [] while True: name = input("输入姓名(输入q退出):") if name == "q": break students.append(name) # 2. 栈(后进先出) stack = [] stack.append(1) # 入栈 stack.append(2) stack.pop() # 出栈 → 2 # 3. 队列(先进先出,用 collections.deque 更好) from collections import deque queue = deque([1, 2, 3]) queue.append(4) # 入队 queue.popleft() # 出队 → 1 # 4. 列表推导式(快速生成) squares = [x**2 for x in range(10) if x % 2 == 0] # [0,4,16,36,64]四、元组(tuple)—— 固定的容器
4.1 本质与特性
元组是不可变的有序序列,像一个被封存的时光胶囊,一旦创建就无法改变。
# 创建方式 t1 = () # 空元组 t2 = (1,) # 单元素元组(注意逗号!) t3 = (1, 2, 3) # 直接创建 t4 = tuple([1, 2, 3]) # 从列表转换 # 核心特性:不可变 t = (1, 2, 3) # t[0] = 100 # TypeError: 'tuple' object does not support item assignment # 但可以整体重新赋值 t = (4, 5, 6) #4.2 常用方法
元组的方法很少,因为不可变:
| 方法 | 说明 | 示例 |
|---|---|---|
count(x) | 统计元素出现次数 | t.count(2) |
index(x) | 返回第一个匹配项索引 | t.index(3) |
len(t) | 获取长度 | len(t) |
4.3 常用场景
# 1. 函数返回多个值 def get_user(): return "张三", 25, "男" # 返回元组 name, age, sex = get_user() # 解包赋值 # 2. 字典的键(元组是不可变的) locations = { (39.9, 116.4): "北京", (31.2, 121.5): "上海" } # 3. 记录不可变的数据 DAYS_OF_WEEK = ("一", "二", "三", "四", "五", "六", "日") MONTHS = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) # 4. 赋值 x, y, z = (1, 2, 3) a, b = b, a # 交换变量五、字典(dict)—— 映射的容器
5.1 本质与特性
字典是键值对(Key-Value)的映射容器,像一本真正的字典——通过"字"(键)快速找到"释义"(值)。
# 创建方式 d1 = {} # 空字典 d2 = {"name": "张三", "age": 20} # 直接创建 d3 = dict(name="张三", age=20) # 关键字参数 d4 = dict([("name","张三"), ("age",20)]) # 从键值对列表 # 核心特性:通过键访问 d = {"name": "张三", "age": 20} print(d["name"]) # 张三 d["city"] = "北京" # 新增5.2 常用方法速查
| 方法 | 说明 | 示例 |
|---|---|---|
d[key] | 访问键(不存在报错) | d["name"] |
d.get(key, default) | 安全访问 | d.get("score", 0) |
d.keys() | 获取所有键 | d.keys() |
d.values() | 获取所有值 | d.values() |
d.items() | 获取所有键值对 | d.items() |
d.update(d2) | 合并字典 | d.update({"age":21}) |
d.pop(key) | 删除并返回值 | d.pop("age") |
d.popitem() | 删除并返回最后一项 | d.popitem() |
d.clear() | 清空字典 | d.clear() |
5.3 常用场景
# 1. 计数器(统计频次) text = "hello world" count = {} for char in text: count[char] = count.get(char, 0) + 1 print(count) # {'h':1, 'e':1, 'l':3, 'o':2, ' ':1, 'w':1, 'r':1, 'd':1} # 2. 配置管理 config = { "host": "localhost", "port": 8080, "debug": True } port = config.get("port", 3000) # 8080 timeout = config.get("timeout", 30) # 30(默认值) # 3. 数据映射 user = {"id": 101, "name": "张三", "age": 20} # 4. 嵌套字典 students = { "s001": {"name": "张三", "age": 20}, "s002": {"name": "李四", "age": 21} } print(students["s001"]["name"]) # 张三 # 5. 字典推导式 squares = {x: x**2 for x in range(5)} # {0:0, 1:1, 2:4, 3:9, 4:16}5.4 注意事项
# 1. 键必须是不可变类型 d = { "name": "张三", # 字符串 101: "学号", # 数字 (1,2): "坐标", # 元组 # [1,2]: "列表" # 列表不能作为键 # {"a":1}: "字典" # 字典不能作为键 } # 2. get() 无法区分"键不存在"和"值为 None" d = {"score": None} print(d.get("score")) # None(键存在) print(d.get("score2")) # None(键不存在) # 用 in 判断 if "score" in d: print(d["score"])六、集合(set)—— 唯一的容器
6.1 本质与特性
集合是无序、唯一的元素容器,像一个自动去重的收藏柜——每个物品只能存放一次。
# 创建方式 s1 = set() # 空集合(注意:{} 是空字典!) s2 = {1, 2, 3} # 直接创建 s3 = set([1, 2, 2, 3]) # 从列表创建 → {1, 2, 3}(自动去重) s4 = {x for x in range(5)} # 集合推导式 → {0,1,2,3,4} # 核心特性:元素唯一 + 无序 s = {1, 2, 3} s.add(2) # 重复,被忽略 s.add(4) # 添加成功 print(s) # {1, 2, 3, 4}(顺序可能不同)6.2 常用方法速查
| 方法 | 说明 | 示例 |
|---|---|---|
add(x) | 添加元素(重复忽略) | s.add(5) |
update(iterable) | 批量添加 | s.update([5,6]) |
remove(x) | 删除元素(不存在报错) | s.remove(3) |
discard(x) | 删除元素(不存在忽略) | s.discard(10) |
pop() | 删除并返回任意元素 | s.pop() |
clear() | 清空集合 | s.clear() |
union(s2)/| | 并集 | s1 | s2 |
intersection(s2)/& | 交集 | s1 & s2 |
difference(s2)/- | 差集 | s1 - s2 |
symmetric_difference(s2)/^ | 对称差集 | s1 ^ s2 |
6.3 常用场景
# 1. 去重 nums = [1, 2, 2, 3, 3, 3, 4] unique = list(set(nums)) # [1, 2, 3, 4] # 2. 成员关系判断 vip_users = {"张三", "李四", "王五"} if "张三" in vip_users: print("VIP用户") # 3. 数据比对 old_data = {"a", "b", "c"} new_data = {"b", "c", "d"} # 新增的元素 added = new_data - old_data # {"d"} # 删除的元素 removed = old_data - new_data # {"a"} # 保留的元素 kept = old_data & new_data # {"b", "c"} # 4. 提取文本中的不同字符 text = "hello world" chars = set(text) # {'h','e','l','o',' ','w','r','d'} # 5. 统计不同单词 words = set("python is great python is powerful".split()) # {'python', 'is', 'great', 'powerful'}