Python核心数据结构通关指南:从入门到精通

📅 2026/7/22 4:26:52
Python核心数据结构通关指南:从入门到精通
一、总览对比表先看全局数据结构是否有序是否可变是否允许重复元素类型索引方式str✅ 有序❌ 不可变✅ 允许重复字符整数下标list✅ 有序✅ 可变✅ 允许重复任意类型整数下标tuple✅ 有序❌ 不可变✅ 允许重复任意类型整数下标dict✅ 有序*✅ 可变❌ Key唯一Key任意不可变类型Value任意Key键set❌ 无序✅ 可变❌ 元素唯一任意不可变类型无索引*注Python 3.7 字典保持插入顺序3.6 及之前为无序。二、字符串str—— 文本处理的基石1. 定义与特性字符串是由字符组成的不可变序列用单引号、双引号或三引号包裹。s1 Hello s2 World s3 多行 字符串2. 常用操作text Python Programming 大小写转换 print(text.lower()) # python programming print(text.upper()) # PYTHON PROGRAMMING print(text.strip()) # Python Programming 去除首尾空格 拆分与拼接 words text.strip().split() # [Python, Programming] new_text -.join(words) # Python-Programming 查找与替换 print(text.find(thon)) # 4 print(text.replace(P, J)) # Jython Jrogramming 格式化 name Alice age 25 print(fMy name is {name}, Im {age}) # f-string推荐 print(My name is {}, Im {}.format(name, age))3. 切片操作所有有序序列通用s Python print(s[0]) # P print(s[-1]) # n print(s[1:4]) # yth [起始:结束:步长] print(s[::-1]) # nohtyP 反转4. 使用场景文本清洗、格式转换日志解析、正则匹配用户输入处理三、列表list—— 最万能的容器1. 定义与特性列表是有序、可变的容器可以存放任意类型的元素用[]表示。empty_list [] mixed [1, hello, 3.14, [1, 2, 3]] # 可以嵌套2. 常用操作fruits [apple, banana, orange] 增 fruits.append(grape) # [apple, banana, orange, grape] fruits.insert(1, mango) # [apple, mango, banana, orange, grape] fruits.extend([kiwi, peach]) # 合并 删 fruits.remove(banana) # 删除第一个匹配项 popped fruits.pop() # 弹出最后一个元素 del fruits[0] # 删除指定下标 改 fruits[0] new_apple 查 print(fruits.index(orange)) # 查找索引 print(apple in fruits) # True/False 排序 numbers [3, 1, 4, 1, 5, 9] numbers.sort() # 原地排序 sorted_numbers sorted(numbers) # 返回新列表 numbers.reverse() # 反转3. 列表推导式Python神器# 生成0~9的平方 squares [x**2 for x in range(10)] # 带条件偶数平方 even_squares [x**2 for x in range(10) if x % 2 0] # 嵌套循环 pairs [(x, y) for x in [1,2,3] for y in [a,b]]4. 使用场景存储动态数据集合批量处理数据作为栈append/pop或队列collections.deque四、元组tuple—— 不可变的“轻量级列表”1. 定义与特性元组是有序、不可变的序列用()表示。一旦创建不可修改。t1 (1, 2, 3) t2 4, 5, 6 # 不加括号也可以 t3 (7,) # 单个元素必须加逗号2. 常用操作只读t (10, 20, 30, 40, 50) 访问 print(t[0]) # 10 print(t[1:3]) # (20, 30) 统计 print(len(t)) # 5 print(t.count(20)) # 1 print(t.index(30)) # 2 解包拆包 a, b, c, d, e t a, *rest t # a10, rest[20,30,40,50]3. 不可变但可包含可变对象t ([1, 2], 3) t[0].append(3) # 可以修改列表内部但不能再赋值 t[0] [...]4. 使用场景函数返回多个值最经典字典的Key因为不可变存储不应改变的数据如配置参数、坐标点比列表更省内存性能略高def get_user(): return Alice, 25, aliceemail.com name, age, email get_user()五、字典dict—— 键值对查询之王1. 定义与特性字典是键值对的映射集合Key必须是不可变类型str/int/tupleValue可以是任意类型。用{}表示。person { name: Bob, age: 30, skills: [Python, Java] }2. 常用操作# 增/改 person[city] New York # 新增 person[age] 31 # 修改 删 del person[skills] # 删除键 age person.pop(age) # 弹出并返回值 last_item person.popitem() # 弹出最后插入的键值对 查安全的获取方式 print(person.get(name, Unknown)) # 不存在返回默认值 print(person.get(salary, 0)) # 不存在返回0 遍历 for key, value in person.items(): print(f{key}: {value}) for key in person.keys(): print(key) for value in person.values(): print(value) 合并字典 d1 {a: 1, b: 2} d2 {b: 3, c: 4} d1.update(d2) # d1变为 {a:1, b:3, c:4} merged {**d1, **d2} # 解包合并Python 3.53. 字典推导式# 反转键值 original {a: 1, b: 2, c: 3} reversed_dict {v: k for k, v in original.items()} # {1: a, 2: b, 3: c} 筛选 filtered {k: v for k, v in original.items() if v 1}4. 使用场景缓存数据用户信息、配置项快速查找O(1)时间复杂度JSON数据处理计数统计配合defaultdict或Counter六、集合set—— 去重和集合运算高手1. 定义与特性集合是无序、元素唯一的可变容器用{}或set()创建。s1 {1, 2, 3, 3, 2} # {1, 2, 3} 自动去重 s2 set([4, 5, 6]) # 从列表创建 empty_set set() # 注意{} 是空字典2. 常用操作a {1, 2, 3, 4} b {3, 4, 5, 6} 增删 a.add(5) a.remove(2) # 不存在会报错 a.discard(10) # 不存在不会报错 a.pop() # 随机移除一个元素 集合运算 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, 2}.issubset(a)) # True print(a.issuperset({1, 2})) # True print(a.isdisjoint({7, 8})) # True3. 使用场景列表快速去重list(set(my_list))共同好友/关注交集运算数据差异对比差集筛选唯一值# 统计一篇文章中出现的不重复单词 text hello world hello python world unique_words set(text.split()) # {hello, world, python}七、性能对比与选型指南操作listtupledictset索引访问O(1)O(1)O(1)按Key❌成员检查inO(n)O(n)O(1)O(1)插入/删除末尾O(1)❌O(1)O(1)插入/删除中间O(n)❌O(1)O(1)内存占用较大较小最大中等选型决策树需要存储文本/字符序列→str需要有序、可变的任意元素集合→list需要有序、不可变的任意元素集合→tuple需要通过Key快速查找Value→dict需要去重或集合运算→set需要作为字典的Key→str/tuple/ 不可变类型八、常见陷阱与避坑指南1. 可变对象作为默认参数# ❌ 错误 def add_item(item, lst[]): lst.append(item) return lst ✅ 正确 def add_item(item, lstNone): if lst is None: lst [] lst.append(item) return lst2. 遍历列表时删除元素# ❌ 会导致索引错乱 for i in range(len(lst)): if lst[i] % 2 0: del lst[i] ✅ 使用列表推导式 lst [x for x in lst if x % 2 ! 0]3. 集合和字典的Key必须是不可变类型# ❌ 列表不能做Key d {[1,2]: value} # TypeError ✅ 元组可以 d {(1,2): value}4. 复制陷阱浅拷贝 vs 深拷贝在 Python 中复制对象时容易遇到浅拷贝和深拷贝的陷阱尤其是当对象包含嵌套的可变元素时。什么是浅拷贝Shallow Copy浅拷贝只复制对象本身而不复制对象内部包含的子对象。对于嵌套的可变对象如列表中的列表、字典中的列表等浅拷贝后的新对象和原对象会共享这些嵌套对象的引用。import copy 原始列表包含嵌套列表 original [[1, 2], [3, 4]] 浅拷贝 - 三种常用方式 shallow1 original.copy() # list 的 copy() 方法 shallow2 list(original) # list() 构造函数 shallow3 original[:] # 切片操作 shallow4 copy.copy(original) # copy 模块的 copy() 函数 修改原始列表的嵌套元素 original[0].append(3) print(原始列表:, original) # [[1, 2, 3], [3, 4]] print(浅拷贝列表:, shallow1) # [[1, 2, 3], [3, 4]] print(它们共享嵌套列表吗?, original[0] is shallow1[0]) # True什么是深拷贝Deep Copy深拷贝会递归复制对象及其所有子对象创建一个完全独立的副本。修改原对象的任何部分都不会影响深拷贝后的对象。import copy 原始列表包含嵌套列表 original [[1, 2], [3, 4]] 深拷贝 deep copy.deepcopy(original) 修改原始列表的嵌套元素 original[0].append(3) print(原始列表:, original) # [[1, 2, 3], [3, 4]] print(深拷贝列表:, deep) # [[1, 2], [3, 4]] print(它们共享嵌套列表吗?, original[0] is deep[0]) # False浅拷贝 vs 深拷贝对比表特性浅拷贝深拷贝复制层级只复制第一层递归复制所有层级嵌套对象共享引用创建独立副本内存占用较小较大递归复制性能较快较慢递归操作适用场景简单对象、无嵌套可变对象复杂嵌套对象、需要完全独立Python 实现list.copy()、dict.copy()、copy.copy()、切片、构造函数copy.deepcopy()不同数据类型的拷贝行为import copy 1. 简单列表无嵌套 simple_list [1, 2, 3] shallow simple_list.copy() deep copy.deepcopy(simple_list) simple_list[0] 100 print(简单列表 - 浅拷贝:, shallow) # [1, 2, 3] print(简单列表 - 深拷贝:, deep) # [1, 2, 3] 对于无嵌套的简单对象浅拷贝和深拷贝效果相同 2. 字典的拷贝 original_dict {a: [1, 2], b: {c: 3}} shallow_dict original_dict.copy() deep_dict copy.deepcopy(original_dict) original_dict[a].append(3) print(字典浅拷贝:, shallow_dict[a]) # [1, 2, 3] print(字典深拷贝:, deep_dict[a]) # [1, 2] 3. 自定义对象 class Person: def init(self, name, friends): self.name name self.friends friends # friends 是一个列表 person1 Person(Alice, [Bob, Charlie]) shallow_person copy.copy(person1) deep_person copy.deepcopy(person1) person1.friends.append(David) print(浅拷贝对象的朋友:, shallow_person.friends) # [Bob, Charlie, David] print(深拷贝对象的朋友:, deep_person.friends) # [Bob, Charlie]实际应用场景与选择建议使用浅拷贝的场景对象只包含不可变类型数字、字符串、元组需要快速创建对象的副本且不关心嵌套对象的独立性嵌套对象本身就是不可变的或者你希望共享这些嵌套对象使用深拷贝的场景对象包含嵌套的可变对象列表中的列表、字典中的列表等需要完全独立的副本修改原对象不影响副本处理配置字典、状态对象等需要隔离修改的场景实现撤销/重做功能时需要保存对象状态特殊注意事项循环引用copy.deepcopy()可以处理循环引用但可能更慢自定义对象可以通过实现__copy__()和__deepcopy__()方法来自定义拷贝行为性能考虑对于大型嵌套结构深拷贝可能消耗大量内存和时间记忆技巧与最佳实践# 快速判断是否需要深拷贝的 checklist # 1. 对象是否包含列表、字典、集合等可变类型的嵌套 # 2. 你希望修改原对象时不影响副本吗 # 3. 副本需要完全独立吗 如果不确定先问自己 如果我修改了原对象的某个嵌套元素我希望副本中的对应元素也改变吗 如果答案是不希望那么你需要深拷贝。 最佳实践示例 def safe_config_update(config, updates): 安全地更新配置不影响原始配置 # 创建配置的深拷贝 new_config copy.deepcopy(config) # 在副本上应用更新 new_config.update(updates) return new_config original_config { database: {host: localhost, port: 3306}, cache: {enabled: True, size: 100} } 安全更新不影响 original_config updated safe_config_update(original_config, {cache: {size: 200}}) print(原始配置缓存大小:, original_config[cache][size]) # 100 print(更新后配置缓存大小:, updated[cache][size]) # 200理解浅拷贝和深拷贝的区别是避免 Python 中隐蔽 bug 的关键。记住当对象包含嵌套的可变元素时默认的复制操作如list.copy()、dict.copy()都是浅拷贝。如果需要完全独立的副本务必使用copy.deepcopy()。总结数据结构一句话记忆str不可变的字符序列文本处理专用list万能的“购物车”什么都能装随时可以改tuple轻量级“密封盒”装进去就不能变dict带标签的“储物柜”凭标签瞬间取物set自动去重的“收纳盒”专注找不同掌握这五种数据结构你就掌握了Python数据处理的核心80%。在实际开发中根据场景选择合适的数据结构远比写出复杂的算法更重要。希望这篇文章能帮你建立起清晰的知识框架。如果你觉得有用欢迎点赞、收藏、转发有任何疑问也欢迎在评论区交流讨论。Happy Coding!