跳到主要内容

字典与集合

掌握键值对存储和去重数据结构

字典(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}")

本章小结

  1. 字典:键值对存储,键唯一且不可变
  2. 字典方法:get、keys、values、items、update
  3. 集合:无序不重复,适合去重和集合运算
  4. 集合运算:并集、交集、差集、对称差集
  5. 推导式:字典推导式和集合推导式

下一步

学会了基本数据结构,下一章学习面向对象编程。

→ 继续阅读:21-面向对象编程基础