Python字典与集合:键值对与去重的艺术
上一篇我们学习了列表和元组,本篇将学习字典(dict)和集合(set),它们是处理键值对和去重场景的利器。
一、字典(Dictionary)
字典是Python中唯一的映射类型,用「键-值对」存储数据,通过键快速查找值,类似于现实中的字典(通过词找释义)。
1. 创建字典
# 空字典empty_dict={}empty_dict2=dict()# 有数据的字典student={"name":"小明","age":18,"city":"北京","is_student":True}# 用dict()创建student2=dict(name="小红",age=17,city="上海")# 键值对列表转字典pairs=[("name","小刚"),("age",19)]student3=dict(pairs)⚠️ 字典的键必须是不可变类型(字符串、数字、元组),不能用列表作为键。
2. 访问字典值
student={"name":"小明","age":18}# 方式一:[]访问(键不存在会报错KeyError)print(student["name"])# 小明# 方式二:get()访问(键不存在返回None或默认值,推荐)print(student.get("age"))# 18print(student.get("gender"))# Noneprint(student.get("gender","未知"))# 未知(指定默认值)3. 添加与修改
student={"name":"小明","age":18}# 添加新键值对student["city"]="北京"print(student)# {'name': '小明', 'age': 18, 'city': '北京'}# 修改已有键的值student["age"]=19print(student)# {'name': '小明', 'age': 19, 'city': '北京'}# 批量更新student.update({"age":20,"major":"计算机"})print(student)4. 删除
student={"name":"小明","age":18,"city":"北京"}# pop:删除指定键并返回值age=student.pop("age")print(age)# 18print(student)# {'name': '小明', 'city': '北京'}# popitem:删除最后一个键值对(Python 3.7+)last=student.popitem()print(last)# ('city', '北京')# del:删除指定键delstudent["name"]# clear:清空字典student.clear()print(student)# {}5. 遍历字典
student={"name":"小明","age":18,"city":"北京"}# 遍历键forkeyinstudent:print(key)# 遍历值forvalueinstudent.values():print(value)# 遍历键值对(推荐)forkey,valueinstudent.items():print(f"{key}:{value}")6. 字典推导式
# 基本形式squares={x:x**2forxinrange(1,6)}print(squares)# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}# 带条件even_squares={x:x**2forxinrange(1,11)ifx%2==0}print(even_squares)# {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}# 字典键值互换original={"a":1,"b":2,"c":3}reversed_dict={v:kfork,vinoriginal.items()}print(reversed_dict)# {1: 'a', 2: 'b', 3: 'c'}7. 字典的嵌套
# 字典嵌套字典students={"001":{"name":"小明","age":18,"scores":[85,90,92]},"002":{"name":"小红","age":17,"scores":[88,95,91]}}print(students["001"]["name"])# 小明print(students["002"]["scores"][1])# 95二、集合(Set)
集合是无序、不重复的元素集合,主要用于去重和集合运算。
1. 创建集合
# 空集合(注意:{}是空字典,不是空集合!)empty_set=set()# 有元素的集合fruits={"苹果","香蕉","橙子","苹果"}# 重复元素会被自动去除print(fruits)# {'苹果', '香蕉', '橙子'}# 从列表创建(去重)nums=set([1,2,2,3,3,3])print(nums)# {1, 2, 3}2. 添加与删除
fruits={"苹果","香蕉"}# add:添加单个元素fruits.add("橙子")print(fruits)# {'苹果', '香蕉', '橙子'}# update:批量添加fruits.update(["葡萄","西瓜"])print(fruits)# remove:删除元素(不存在会报错)fruits.remove("苹果")# discard:删除元素(不存在不报错,推荐)fruits.discard("不存在的水果")# pop:随机删除一个元素并返回removed=fruits.pop()# clear:清空fruits.clear()3. 集合运算
a={1,2,3,4,5}b={4,5,6,7,8}# 并集:两个集合所有元素print(a|b)# {1, 2, 3, 4, 5, 6, 7, 8}print(a.union(b))# 交集:两个集合共同元素print(a&b)# {4, 5}print(a.intersection(b))# 差集:a有但b没有print(a-b)# {1, 2, 3}print(a.difference(b))# 对称差集:只在一个集合中出现的元素print(a^b)# {1, 2, 3, 6, 7, 8}print(a.symmetric_difference(b))# 子集判断print({1,2}<=a)# Trueprint({1,2}.issubset(a))# 超集判断print(a>={1,2})# True4. 集合推导式
# 生成1-10中偶数的集合evens={xforxinrange(1,11)ifx%2==0}print(evens)# {2, 4, 6, 8, 10}三、字典与集合的应用场景
1. 字典的典型场景
- 配置信息:键值对存储配置
- 计数统计:统计元素出现次数
- 缓存/映射:快速查找
- JSON数据:与JSON格式天然对应
2. 集合的典型场景
- 去重:列表去重最简洁的方式
- 成员判断:集合的in操作比列表快得多(O(1) vs O(n))
- 集合运算:交集、并集、差集等数学运算
四、实战:词频统计器
importrefromcollectionsimportCounterdefword_frequency(text):"""统计文本词频"""# 提取单词(转小写)words=re.findall(r"[a-zA-Z]+",text.lower())# 方法一:手动统计freq={}forwordinwords:freq[word]=freq.get(word,0)+1returnfreqdefword_frequency_counter(text):"""用Counter统计(更简洁)"""words=re.findall(r"[a-zA-Z]+",text.lower())returnCounter(words)# 测试text="""Python is a great programming language. Python is easy to learn. I love Python programming! Programming is fun."""freq=word_frequency(text)# 按频率排序输出Top5print("词频Top5:")forword,countinsorted(freq.items(),key=lambdax:x[1],reverse=True)[:5]:print(f"{word}:{count}次")# 用Counter的most_commoncounter=word_frequency_counter(text)print("\nCounter Top3:",counter.most_common(3))输出:
词频Top5: python: 3次 is: 3次 programming: 3次 a: 1次 great: 1次 Counter Top3: [('python', 3), ('is', 3), ('programming', 3)]五、实战:找共同好友
# 用集合找共同好友friends={"小明":{"小红","小刚","小丽","小强"},"小红":{"小明","小刚","小美","小强"},"小刚":{"小明","小红","小丽"},"小丽":{"小明","小刚","小美"},}defcommon_friends(name1,name2):"""找两个人的共同好友"""ifname1notinfriendsorname2notinfriends:returnset()returnfriends[name1]&friends[name2]# 小明和小红的共同好友print("小明和小红的共同好友:",common_friends("小明","小红"))# 输出: {'小刚', '小强'}# 谁的好友最多most_friends=max(friends,key=lambdax:len(friends[x]))print(f"好友最多的人:{most_friends}({len(friends[most_friends])}个好友)")# 找出所有人的共同好友all_common=set.intersection(*friends.values())print("所有人的共同好友:",all_commonifall_commonelse"没有")六、常见坑点
- 空集合的创建:
{}是空字典,空集合要用set() - 字典键的类型:键必须是不可变类型,列表不能作为键
- 字典遍历中删除:遍历时不能修改字典大小,应遍历列表副本
# 错误forkind:ifcondition:deld[k]# 会报错# 正确forkinlist(d.keys()):ifcondition:deld[k] - 集合是无序的:不能通过索引访问集合元素
- 字典的get vs []:get不会报错,[]会报错,优先用get
七、课后练习
- 编写程序,输入一段文本,统计每个中文字符出现的次数
- 编写程序,去除列表中的重复元素并保持原顺序
- 编写程序,给定两个列表,找出它们的共同元素和各自独有的元素
- 编写程序,用字典实现一个简单的通讯录(增删改查功能)
八、小结
本篇学习了字典的增删改查、遍历、推导式,以及集合的创建、运算和典型应用场景。字典适合键值对映射和快速查找,集合适合去重和集合运算,两者都是Python中非常高效的数据结构。
📌下一篇预告:《入门阶段实战:学生成绩管理系统(控制台版)》
本专栏持续更新中,欢迎点赞、收藏、关注三连支持!🐍