Python 入门教程(五):字典与集合
1683 字
8 分钟
Python 入门教程(五):字典与集合
本篇目标
列表用”位置”找数据(nums[0]),但很多时候我们需要用”名字”找数据——学号查成绩、用户名查密码、单词查释义。字典就是干这个的;集合则是自动去重的数学容器。学完本篇,Python 四大容器(列表/元组/字典/集合)就集齐了。
一、字典:键值对映射
创建与基本访问
# 键值对:{键: 值, ...}student = { "name": "小明", "age": 18, "major": "计算机科学", "scores": {"python": 90, "cpp": 85}, # 字典可以嵌套}
print(student["name"]) # 小明print(student["scores"]["python"]) # 90(链式访问嵌套)
# 空字典empty = {}also_empty = dict()
# dict() 构造ages = dict(小明=18, 小红=17) # {'小明': 18, '小红': 17}pairs = dict([("a", 1), ("b", 2)]) # {'a': 1, 'b': 2}键的要求:必须不可变(字符串/数字/元组可以,列表不行),且唯一(重复定义后者覆盖前者)。
增与改
user = {"name": "小明"}
user["age"] = 18 # 键不存在 → 新增user["age"] = 19 # 键已存在 → 修改user.update({"city": "北京", "age": 20}) # 批量增改print(user) # {'name': '小明', 'age': 20, 'city': '北京'}查:安全访问三件套
user = {"name": "小明", "age": 18}
# 1. [] 直接访问:键不存在直接报错print(user["name"]) # 小明# print(user["email"]) # ❌ KeyError!
# 2. .get():不存在返回 None(或默认值),推荐print(user.get("email")) # Noneprint(user.get("email", "未填写")) # 未填写
# 3. in:先判断再访问if "age" in user: print("年龄:", user["age"])Tip
日常写法用 .get();确定键必存在(如自己刚放进去的)才用 []。
setdefault:不存在才设置
stats = {}# 统计字符出现次数的优雅写法for ch in "hello": stats.setdefault(ch, 0) # 没有该键就先设为 0 stats[ch] += 1print(stats) # {'h': 1, 'e': 1, 'l': 2, 'o': 1}删
user = {"name": "小明", "age": 18, "city": "北京"}
age = user.pop("age") # 删除并返回值:18del user["city"] # del 语句删除user.pop("email", None) # 键不存在不报错(给了默认值)
last = user.popitem() # 删除并返回最后一个键值对print(user) # {}遍历三件套
scores = {"小明": 90, "小红": 85, "小刚": 92}
# 遍历键(默认就是遍历键)for name in scores: print(name)
# 遍历值for score in scores.values(): print(score)
# 同时遍历键和值(最常用)for name, score in scores.items(): print(f"{name}: {score} 分")其他常用操作
scores = {"小明": 90, "小红": 85}
print(len(scores)) # 2print(max(scores, key=scores.get)) # 小刚→最高分的人名(key=按值比较)print(list(scores.keys())) # ['小明', '小红']print(list(scores.values())) # [90, 85]
# 合并(Python 3.5+)extra = {"小刚": 92}all_scores = {**scores, **extra}# Python 3.9+ 更简洁:all_scores = scores | extra案例:词频统计(字典最经典应用)
text = """python is simple and python is powerfullearn python and code python"""
# 方法:setdefault 计数freq = {}for word in text.split(): freq.setdefault(word, 0) freq[word] += 1
# 按次数降序输出 Top 3for word, count in sorted(freq.items(), key=lambda x: x[1], reverse=True)[:3]: print(f"{word}: {count} 次")# python: 4 次# and: 2 次# is: 2 次案例:通讯录(嵌套字典)
contacts = { "小明": {"phone": "138xxxx", "city": "北京", "tags": ["同学", "编程组"]}, "小红": {"phone": "139xxxx", "city": "上海", "tags": ["同学"]},}
def show(name): info = contacts.get(name) if info is None: print(f"没有 {name} 的联系方式") return tags = "/".join(info["tags"]) print(f"{name}|{info['phone']}|{info['city']}|标签: {tags}")
def search_by_city(city): found = [n for n, i in contacts.items() if i["city"] == city] print(f"{city} 的联系人: {found}")
show("小明") # 小明|138xxxx|北京|标签: 同学/编程组search_by_city("上海") # 上海 的联系人: ['小红']二、集合:去重与集合运算
创建与去重
# 花括号内是元素(不是键值对)就是集合fruits = {"apple", "banana", "apple", "cherry"}print(fruits) # {'apple', 'banana', 'cherry'} 自动去重!print(len(fruits)) # 3
# ⚠️ 空花括号是字典不是集合!empty_dict = {}empty_set = set() # 空集合必须用 set()
# 从列表去重(最常用场景)nums = [1, 3, 2, 3, 1, 5]unique = list(set(nums))print(unique) # [1, 2, 3, 5](顺序不保证!)
# 去重且保序的写法unique_ordered = list(dict.fromkeys(nums))print(unique_ordered) # [1, 3, 2, 5] ✓ 保持原序增删
s = {1, 2, 3}
s.add(4) # 添加单个s.update([5, 6]) # 添加多个s.remove(9) # ❌ 不存在会 KeyErrors.discard(9) # ✓ 不存在也不报错(推荐)s.pop() # 随机弹出一个元素print(s)集合运算:交并差
两个班的选课情况对比:
class_a = {"python", "cpp", "java", "go"}class_b = {"python", "java", "rust", "js"}
# 交集:都选了的课print(class_a & class_b) # {'python', 'java'}print(class_a.intersection(class_b)) # 同上
# 并集:所有人选过的课print(class_a | class_b) # {'python','cpp','java','go','rust','js'}
# 差集:A 选了 B 没选的print(class_a - class_b) # {'cpp', 'go'}
# 对称差:只有一方选了的(并集 - 交集)print(class_a ^ class_b) # {'cpp', 'go', 'rust', 'js'}
# 子集与超集print({"python"} <= class_a) # True 子集判断print(class_a.issubset(class_a | class_b)) # True助记:& 交(都有的)、| 并(合起来)、- 差(我有你没有)、^ 异(不共有的)。
集合推导式与 frozenset
squares = {i**2 for i in range(1, 6)}print(squares) # {1, 4, 9, 16, 25}
# frozenset:不可变集合,可作为字典键fs = frozenset([1, 2, 3])# fs.add(4) # ❌ 不可变cache = {fs: "结果"} # ✓ 合法成员测试的性能优势
in 集合是 O(1),in 列表是 O(n)——数据量大时差距巨大:
import time
big_list = list(range(1_000_000))big_set = set(big_list)
t1 = time.time()for _ in range(100): 999_999 in big_listt2 = time.time()for _ in range(100): 999_999 in big_sett3 = time.time()
print(f"列表查找: {(t2-t1)*1000:.1f}ms")print(f"集合查找: {(t3-t2)*1000:.1f}ms") # 快百倍以上实践建议:频繁判断”某元素是否在一堆数据里”时,把那堆数据转成集合。
三、四大容器总对比
| 特性 | 列表 list | 元组 tuple | 字典 dict | 集合 set |
|---|---|---|---|---|
| 符号 | [1,2] | (1,2) | {"k":v} | {1,2} |
| 有序 | ✓ | ✓ | ✓(3.7+保序) | ✗ |
| 可变 | ✓ | ✗ | ✓ | ✓ |
| 允许重复 | ✓ | ✓ | 键不行 | ✗ |
| 典型用途 | 序列数据 | 固定数据 | 映射查找 | 去重/集合运算 |
| 查找效率 | O(n) | O(n) | O(1) 按键 | O(1) |
选型口诀:排队用列表、锁死用元组、查名用字典、去重用集合。
小练习
- 统计一句话中每个汉字出现的次数,按次数降序输出(用字典)
- 两个班学生名单去重合并:A 班
["a","b","c","d"]、B 班["c","d","e","f"],输出所有人都名单与”只在一个班”的人 - 实现简单的英汉字典:支持查词(不存在提示”未收录”)、添加新词、遍历输出所有词条
- 用集合推导式生成 1~100 中能被 3 或 5 整除的数的平方集合
本篇小结
- 字典按键存取 O(1);安全访问用
.get();计数用setdefault - 遍历三件套:
keys()/values()/items() - 合并字典:
{**a, **b}或 3.9+ 的a | b - 集合自动去重;
& | - ^四大运算;discard比remove安全 - 空集合用
set();频繁成员测试选集合不选列表 - 四大容器选型口诀:排队列表、锁死元组、查名字典、去重集合
下一篇:函数——把代码封装成可复用的积木。
本系列为 Cyber先锋社原创教程。词频统计是面试与实战双高频题,务必独立写一遍。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
Python 入门教程(五):字典与集合
https://www.cyberpioneer.club/posts/python-tutorial-05/相关文章智能推荐
1
Python 入门教程(四):列表与元组
Python 教程深入 Python 最核心的容器:列表的增删改查全家桶、切片操作、排序与遍历技巧、浅拷贝与深拷贝的坑、元组的不可变特性与解包,附购物车与成绩统计完整案例。
2
Python 入门教程(七):迭代器与生成器
Python 教程理解 for 循环背后的迭代协议、迭代器与可迭代对象的区别、生成器函数与生成器表达式的懒加载、yield 的执行原理、无限序列与管道式数据处理,掌握省内存的 Pythonic 写法。
3
Python 入门教程(三):条件判断与循环控制
Python 教程完整讲解 if/elif/else 分支结构、while 与 for 循环、range 与 enumerate、break/continue/else 子句、循环嵌套与推导式,用经典练习题巩固流程控制。
4
Python 入门教程(九):文件操作与异常处理
Python 教程完整讲解文件读写模式与 with 上下文管理、编码问题排查、逐行处理与追加写入,异常处理全语法(try/except/else/finally/raise)、自定义异常与工程化容错策略,附日志记录实战。
5
Python 入门教程(二):运算符与字符串详解
Python 教程详解 Python 全部七类运算符(算术/比较/赋值/逻辑/成员/身份/位运算)与字符串的索引切片、常用方法、格式化输出,配套大量可运行示例。
随机文章随机推荐



