字典与集合
掌握键值对存储和去重数据结构
字典(Dict)
什么是字典
字典 是键值对(key-value)的无序集合。
# 创建字典
person = {
"name": "张三",
"age": 25,
"city": "北京"
}
# 空字典
empty = {}
empty = dict()
# 使用dict()创建
person = dict(name="张三", age=25)
字典特点
- 键值对:每个元素由键和值组成
- 键唯一:键不能重复
- 键不可变:键必须是不可变类型(字符串、数字、元组)
- 值任意:值可以是任何类型
- 无序:Python 3.7+ 保持插入顺序
字典基本操作
访问元素
person = {"name": "张三", "age": 25, "city": "北京"}
# 通过键访问
print(person["name"]) # 张三
# 使用get(键不存在时返回默认值)
print(person.get("age")) # 25
print(person.get("email")) # None
print(person.get("email", "无")) # 无
# 检查键是否存在
print("name" in person) # True
print("email" in person) # False
修改和添加
person = {"name": "张三", "age": 25}
# 修改值
person["age"] = 26
print(person) # {'name': '张三', 'age': 26}
# 添加新键值对
person["city"] = "北京"
print(person) # {'name': '张三', 'age': 26, 'city': '北京'}
# update:批量更新
person.update({"email": "test@example.com", "age": 27})
删除元素
person = {"name": "张三", "age": 25, "city": "北京"}
# pop:删除并返回值
age = person.pop("age")
print(age) # 25
print(person) # {'name': '张三', 'city': '北京'}
# del:删除键值对
del person["city"]
# popitem:删除最后一个键值对
last = person.popitem()
# clear:清空字典
person.clear()
字典遍历
person = {"name": "张三", "age": 25, "city": "北京"}
# 遍历键
for key in person:
print(key)
for key in person.keys():
print(key)
# 遍历值
for value in person.values():
print(value)
# 遍历键值对
for key, value in person.items():
print(f"{key}: {value}")
字典方法
person = {"name": "张三", "age": 25}
# keys():获取所有键
print(list(person.keys())) # ['name', 'age']
# values():获取所有值
print(list(person.values())) # ['张三', 25]
# items():获取所有键值对
print(list(person.items())) # [('name', '张三'), ('age', 25)]
# copy():浅复制
copy_person = person.copy()
# setdefault:获取值,不存在则设置默认值
email = person.setdefault("email", "default@example.com")
print(email) # default@example.com
print(person) # {'name': '张三', 'age': 25, 'email': 'default@example.com'}
字典推导式
# {键表达式: 值表达式 for 变量 in 可迭代对象}
# 创建平方字典
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(10) if x % 2 == 0}
print(even_squares) # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
# 反转字典
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'}
嵌套字典
# 嵌套结构
students = {
"s001": {
"name": "张三",
"scores": {"math": 85, "english": 90}
},
"s002": {
"name": "李四",
"scores": {"math": 92, "english": 88}
}
}
# 访问嵌套数据
print(students["s001"]["name"]) # 张三
print(students["s001"]["scores"]["math"]) # 85
# 遍历嵌套字典
for sid, info in students.items():
print(f"{info['name']}的数学成绩:{info['scores']['math']}")
集合(Set)
什么是集合
集合 是无序的、不重复的元素集合。
# 创建集合
fruits = {"苹果", "香蕉", "橙子"}
numbers = {1, 2, 3, 4, 5}
# 空集合(不能用{},那是空字典)
empty = set()
# 从列表创建(去重)
numbers = set([1, 2, 2, 3, 3, 3])
print(numbers) # {1, 2, 3}
集合特点
- 无序:元素没有固定顺序
- 唯一:元素不能重复
- 可变:可以添加删除元素
- 元素不可变:元素必须是不可变类型
集合基本操作
添加和删除
fruits = {"苹果", "香蕉"}
# 添加单个元素
fruits.add("橙子")
print(fruits) # {'苹果', '香蕉', '橙子'}
# 添加多个元素
fruits.update(["葡萄", "西瓜"])
# 删除元素
fruits.remove("香蕉") # 不存在会报错
fruits.discard("芒果") # 不存在不报错
item = fruits.pop() # 随机删除一个
# 清空
fruits.clear()
集合运算
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))
集合关系
a = {1, 2, 3}
b = {1, 2, 3, 4, 5}
c = {1, 2, 3}
# 子集
print(a <= b) # True(a是b的子集)
print(a.issubset(b))
# 超集
print(b >= a) # True(b是a的超集)
print(b.issuperset(a))
# 相等
print(a == c) # True
# 不相交
d = {6, 7, 8}
print(a.isdisjoint(d)) # True(没有共同元素)
集合推导式
# {表达式 for 变量 in 可迭代对象}
# 平方数集合
squares = {x**2 for x in range(1, 6)}
print(squares) # {1, 4, 9, 16, 25}
# 带条件
evens = {x for x in range(10) if x % 2 == 0}
print(evens) # {0, 2, 4, 6, 8}
实际应用
去重
# 列表去重
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique = list(set(numbers))
print(unique) # [1, 2, 3, 4]
# 保持顺序的去重
def deduplicate(lst):
seen = set()
result = []
for item in lst:
if item not in seen:
seen.add(item)
result.append(item)
return result
统计词频
text = "apple banana apple cherry banana apple"
words = text.split()
# 方法1:字典
word_count = {}
for word in words:
word_count[word] = word_count.get(word, 0) + 1
print(word_count) # {'apple': 3, 'banana': 2, 'cherry': 1}
# 方法2:Counter
from collections import Counter
word_count = Counter(words)
print(word_count.most_common(2)) # [('apple', 3), ('banana', 2)]
分组数据
students = [
{"name": "张三", "class": "A"},
{"name": "李四", "class": "B"},
{"name": "王五", "class": "A"},
{"name": "赵六", "class": "B"}
]
# 按班级分组
groups = {}
for student in students:
cls = student["class"]
if cls not in groups:
groups[cls] = []
groups[cls].append(student["name"])
print(groups) # {'A': ['张三', '王五'], 'B': ['李四', '赵六']}
练习
练习1:字典操作
# 创建学生成绩字典,完成以下操作
# 1. 添加学生成绩
# 2. 修改某学生成绩
# 3. 删除某学生
# 4. 计算平均分
scores = {"张三": 85, "李四": 92, "王五": 78}
# 参考答案
scores["赵六"] = 88 # 添加
scores["张三"] = 90 # 修改
del scores["李四"] # 删除
avg = sum(scores.values()) / len(scores)
print(f"平均分:{avg}")
练习2:集合应用
# 找出两个列表的共同元素和各自独有元素
list1 = [1, 2, 3, 4, 5]
list2 = [4, 5, 6, 7, 8]
# 参考答案
set1, set2 = set(list1), set(list2)
common = set1 & set2
only1 = set1 - set2
only2 = set2 - set1
print(f"共同:{common}")
print(f"list1独有:{only1}")
print(f"list2独有:{only2}")
本章小结
- 字典:键值对存储,键唯一且不可变
- 字典方法:get、keys、values、items、update
- 集合:无序不重复,适合去重和集合运算
- 集合运算:并集、交集、差集、对称差集
- 推导式:字典推导式和集合推导式
下一步
学会了基本数据结构,下一章学习面向对象编程。
→ 继续阅读:21-面向对象编程基础