Python字典与集合:键值对与去重的艺术

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"))        # 18
print(student.get("gender"))     # None
print(student.get("gender", "未知"))  # 未知(指定默认值)

3. 添加与修改

student = {"name": "小明", "age": 18}

# 添加新键值对
student["city"] = "北京"
print(student)  # {'name': '小明', 'age': 18, 'city': '北京'}

# 修改已有键的值
student["age"] = 19
print(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)      # 18
print(student)  # {'name': '小明', 'city': '北京'}

# popitem:删除最后一个键值对(Python 3.7+)
last = student.popitem()
print(last)     # ('city', '北京')

# del:删除指定键
del student["name"]

# clear:清空字典
student.clear()
print(student)  # {}

5. 遍历字典

student = {"name": "小明", "age": 18, "city": "北京"}

# 遍历键
for key in student:
    print(key)

# 遍历值
for value in student.values():
    print(value)

# 遍历键值对(推荐)
for key, value in student.items():
    print(f"{key}: {value}")

6. 字典推导式

# 基本形式
squares = {x: x ** 2 for x in range(1, 6)}
print(squares)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# 带条件
even_squares = {x: x ** 2 for x in range(1, 11) if x % 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: k for k, v in original.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)  # True
print({1, 2}.issubset(a))

# 超集判断
print(a >= {1, 2})  # True

4. 集合推导式

# 生成1-10中偶数的集合
evens = {x for x in range(1, 11) if x % 2 == 0}
print(evens)  # {2, 4, 6, 8, 10}

三、字典与集合的应用场景

1. 字典的典型场景

  • 配置信息:键值对存储配置
  • 计数统计:统计元素出现次数
  • 缓存/映射:快速查找
  • JSON数据:与JSON格式天然对应

2. 集合的典型场景

  • 去重:列表去重最简洁的方式
  • 成员判断:集合的in操作比列表快得多(O(1) vs O(n))
  • 集合运算:交集、并集、差集等数学运算

四、实战:词频统计器

import re
from collections import Counter

def word_frequency(text):
    """统计文本词频"""
    # 提取单词(转小写)
    words = re.findall(r"[a-zA-Z]+", text.lower())
    
    # 方法一:手动统计
    freq = {}
    for word in words:
        freq[word] = freq.get(word, 0) + 1
    
    return freq

def word_frequency_counter(text):
    """用Counter统计(更简洁)"""
    words = re.findall(r"[a-zA-Z]+", text.lower())
    return Counter(words)

# 测试
text = """Python is a great programming language. 
Python is easy to learn. 
I love Python programming! 
Programming is fun."""

freq = word_frequency(text)

# 按频率排序输出Top5
print("词频Top5:")
for word, count in sorted(freq.items(), key=lambda x: x[1], reverse=True)[:5]:
    print(f"  {word}: {count}次")

# 用Counter的most_common
counter = 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 = {
    "小明": {"小红", "小刚", "小丽", "小强"},
    "小红": {"小明", "小刚", "小美", "小强"},
    "小刚": {"小明", "小红", "小丽"},
    "小丽": {"小明", "小刚", "小美"},
}

def common_friends(name1, name2):
    """找两个人的共同好友"""
    if name1 not in friends or name2 not in friends:
        return set()
    return friends[name1] & friends[name2]

# 小明和小红的共同好友
print("小明和小红的共同好友:", common_friends("小明", "小红"))
# 输出: {'小刚', '小强'}

# 谁的好友最多
most_friends = max(friends, key=lambda x: len(friends[x]))
print(f"好友最多的人: {most_friends}{len(friends[most_friends])}个好友)")

# 找出所有人的共同好友
all_common = set.intersection(*friends.values())
print("所有人的共同好友:", all_common if all_common else "没有")

六、常见坑点

  1. 空集合的创建{} 是空字典,空集合要用 set()
  2. 字典键的类型:键必须是不可变类型,列表不能作为键
  3. 字典遍历中删除:遍历时不能修改字典大小,应遍历列表副本
    # 错误
    for k in d:
        if condition:
            del d[k]  # 会报错
    
    # 正确
    for k in list(d.keys()):
        if condition:
            del d[k]
    
  4. 集合是无序的:不能通过索引访问集合元素
  5. 字典的get vs []:get不会报错,[]会报错,优先用get

七、课后练习

  1. 编写程序,输入一段文本,统计每个中文字符出现的次数
  2. 编写程序,去除列表中的重复元素并保持原顺序
  3. 编写程序,给定两个列表,找出它们的共同元素和各自独有的元素
  4. 编写程序,用字典实现一个简单的通讯录(增删改查功能)

八、小结

本篇学习了字典的增删改查、遍历、推导式,以及集合的创建、运算和典型应用场景。字典适合键值对映射和快速查找,集合适合去重和集合运算,两者都是Python中非常高效的数据结构。

📌 下一篇预告:《入门阶段实战:学生成绩管理系统(控制台版)》


本专栏持续更新中,欢迎点赞、收藏、关注三连支持!🐍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Htr_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值