Python字典与集合
学习目标
通过本集的学习,你将能够:
- 理解字典的键值对概念
- 掌握字典的基本操作
- 理解集合的特性
- 使用集合进行数学运算
- 选择合适的数据结构
1. 字典的键值对
字典是Python中另一种重要的数据结构,它存储键值对(key-value pairs)。
1.1 创建字典
# 空字典
empty_dict = {}
print(empty_dict) # 输出: {}
# 使用大括号创建
person = {
"name": "张三",
"age": 25,
"city": "北京"
}
print(person)
# 使用dict()创建
person2 = dict(name="李四", age=30, city="上海")
print(person2)
# 键可以是不可变类型(字符串、数字、元组等)
# 值可以是任意类型
mixed = {
1: "one",
"two": 2,
(3, 4): "tuple key",
"nested": {"a": 1, "b": 2}
}
print(mixed)字典的ASCII图表示:
字典: {"name": "张三", "age": 25, "city": "北京"}
┌─────────────┐
│ "name" │───→ "张三"
├─────────────┤
│ "age" │───→ 25
├─────────────┤
│ "city" │───→ "北京"
└─────────────┘
键 (Key) 值 (Value)1.2 访问字典元素
person = {"name": "张三", "age": 25, "city": "北京"}
# 使用 [] 访问
print(person["name"]) # 输出: 张三
print(person["age"]) # 输出: 25
# 使用 get() 访问(更安全)
print(person.get("name")) # 输出: 张三
print(person.get("gender")) # 输出: None(键不存在时返回None)
print(person.get("gender", "未知")) # 输出: 未知(指定默认值)
# 检查键是否存在
print("name" in person) # 输出: True
print("gender" in person) # 输出: False2. 字典的基本操作
2.1 添加和修改元素
person = {"name": "张三", "age": 25}
# 添加新键值对
person["city"] = "北京"
print(person) # 输出: {'name': '张三', 'age': 25, 'city': '北京'}
# 修改已有键的值
person["age"] = 26
print(person) # 输出: {'name': '张三', 'age': 26, 'city': '北京'}
# 使用 update() 批量更新
person.update({"age": 27, "gender": "男", "job": "工程师"})
print(person)2.2 删除元素
person = {"name": "张三", "age": 25, "city": "北京", "job": "工程师"}
# 使用 del 删除
del person["job"]
print(person)
# 使用 pop() 删除并返回值
age = person.pop("age")
print(age) # 输出: 25
print(person) # 输出: {'name': '张三', 'city': '北京'}
# pop() 可以指定默认值
gender = person.pop("gender", "未知")
print(gender) # 输出: 未知
# 使用 popitem() 删除最后一个键值对(Python 3.7+)
last = person.popitem()
print(last) # 输出: ('city', '北京')
print(person) # 输出: {'name': '张三'}
# 使用 clear() 清空字典
person.clear()
print(person) # 输出: {}2.3 字典方法
person = {"name": "张三", "age": 25, "city": "北京"}
# 获取所有键
keys = person.keys()
print(keys) # 输出: dict_keys(['name', 'age', 'city'])
print(list(keys)) # 输出: ['name', 'age', 'city']
# 获取所有值
values = person.values()
print(values) # 输出: dict_values(['张三', 25, '北京'])
print(list(values)) # 输出: ['张三', 25, '北京']
# 获取所有键值对
items = person.items()
print(items) # 输出: dict_items([('name', '张三'), ('age', 25), ('city', '北京')])
print(list(items)) # 输出: [('name', '张三'), ('age', 25), ('city', '北京')]
# 复制字典
person2 = person.copy()
print(person2)
# 长度
print(len(person)) # 输出: 32.4 遍历字典
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}")2.5 字典推导式
# 基本字典推导式
squares = {x: x * x for x in range(5)}
print(squares) # 输出: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# 带条件的字典推导式
even_squares = {x: x * x for x in range(10) if x % 2 == 0}
print(even_squares) # 输出: {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
# 从两个列表创建字典
keys = ["name", "age", "city"]
values = ["张三", 25, "北京"]
person = {k: v for k, v in zip(keys, values)}
print(person)
# 反转字典(键值互换)
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'}3. 集合的特性
集合是无序、不重复的元素集合。
3.1 创建集合
# 空集合(注意:{}是空字典,不是空集合)
empty_set = set()
print(empty_set) # 输出: set()
# 使用大括号创建
fruits = {"apple", "banana", "cherry"}
print(fruits)
# 集合自动去重
numbers = {1, 2, 2, 3, 3, 3, 4}
print(numbers) # 输出: {1, 2, 3, 4}
# 使用set()创建
letters = set("hello")
print(letters) # 输出: {'h', 'e', 'l', 'o'}
list_to_set = set([1, 2, 3, 2, 1])
print(list_to_set) # 输出: {1, 2, 3}集合的ASCII图表示:
集合: {1, 2, 3, 4}
┌───┐ ┌───┐ ┌───┐ ┌───┐
│ 1 │ │ 2 │ │ 3 │ │ 4 │
└───┘ └───┘ └───┘ └───┘
特点:
- 无序:没有固定顺序
- 不重复:每个元素唯一
- 可变:可以添加/删除元素3.2 集合操作
fruits = {"apple", "banana", "cherry"}
# 添加元素
fruits.add("date")
print(fruits) # 输出: {'apple', 'banana', 'cherry', 'date'}
# 添加多个元素
fruits.update(["elderberry", "fig"])
print(fruits)
# 删除元素
fruits.remove("banana")
print(fruits)
# discard():删除不存在的元素不会报错
fruits.discard("banana") # 不会报错
# pop():随机删除一个元素并返回
popped = fruits.pop()
print(popped)
print(fruits)
# 清空集合
fruits.clear()
print(fruits) # 输出: set()3.3 集合运算
A = {1, 2, 3, 4}
B = {3, 4, 5, 6}
# 并集:所有在A或B中的元素
union = A | B
print(union) # 输出: {1, 2, 3, 4, 5, 6}
print(A.union(B))
# 交集:同时在A和B中的元素
intersection = A & B
print(intersection) # 输出: {3, 4}
print(A.intersection(B))
# 差集:在A中但不在B中的元素
difference = A - B
print(difference) # 输出: {1, 2}
print(A.difference(B))
# 对称差集:在A或B中,但不同时在两者中
symmetric_diff = A ^ B
print(symmetric_diff) # 输出: {1, 2, 5, 6}
print(A.symmetric_difference(B))集合运算的ASCII图:
并集 A | B:
┌─────────┐
│ A ● │
│ ● ● │
│ ● ● B │
└─────────┘
交集 A & B:
┌─────────┐
│ A │
│ ●● │
│ B │
└─────────┘
差集 A - B:
┌─────────┐
│ A ●● │
│ │
│ B │
└─────────┘3.4 集合关系
A = {1, 2, 3}
B = {1, 2, 3, 4, 5}
C = {4, 5, 6}
# 子集:A的所有元素都在B中
print(A.issubset(B)) # 输出: True
print(A <= B) # 输出: True
# 超集:B包含A的所有元素
print(B.issuperset(A)) # 输出: True
print(B >= A) # 输出: True
# 真子集
print(A < B) # 输出: True
print(A < A) # 输出: False
# 不相交:没有共同元素
print(A.isdisjoint(C)) # 输出: True
print(A.isdisjoint(B)) # 输出: False4. frozenset:不可变集合
# 创建frozenset
fs = frozenset([1, 2, 3, 4])
print(fs) # 输出: frozenset({1, 2, 3, 4})
# frozenset可以作为字典的键
d = {fs: "这是一个frozenset"}
print(d)
# frozenset支持集合运算
fs2 = frozenset([3, 4, 5, 6])
print(fs & fs2) # 输出: frozenset({3, 4})
# 但不能修改
# fs.add(5) # 错误:AttributeError5. 实用案例
5.1 案例1:单词频率统计
# word_count.py
def count_words(text):
"""统计单词出现频率"""
# 转换为小写并分割
words = text.lower().split()
# 去除标点
words = [word.strip(",.!?;:") for word in words]
# 统计频率
word_count = {}
for word in words:
if word:
word_count[word] = word_count.get(word, 0) + 1
return word_count
def print_word_count(word_count):
"""打印单词频率"""
# 按频率排序
sorted_words = sorted(word_count.items(), key=lambda x: x[1], reverse=True)
for word, count in sorted_words:
print(f"{word}: {count}")
# 测试
sample_text = """Python is a great language. Python is easy to learn.
I love Python! Python is fun."""
word_count = count_words(sample_text)
print("单词频率统计:")
print_word_count(word_count)
# 使用集合找出唯一单词
unique_words = set(word_count.keys())
print(f"\n唯一单词数: {len(unique_words)}")
print("唯一单词:", unique_words)5.2 案例2:通讯录管理
# contact_book.py
class ContactBook:
def __init__(self):
self.contacts = {}
def add(self, name, phone, email=None):
"""添加联系人"""
self.contacts[name] = {
"phone": phone,
"email": email
}
print(f"已添加联系人: {name}")
def search(self, name):
"""查找联系人"""
if name in self.contacts:
info = self.contacts[name]
print(f"{name}:")
print(f" 电话: {info['phone']}")
if info['email']:
print(f" 邮箱: {info['email']}")
else:
print(f"未找到联系人: {name}")
def delete(self, name):
"""删除联系人"""
if name in self.contacts:
del self.contacts[name]
print(f"已删除联系人: {name}")
else:
print(f"未找到联系人: {name}")
def list_all(self):
"""列出所有联系人"""
if not self.contacts:
print("通讯录为空")
return
print("所有联系人:")
for name in sorted(self.contacts.keys()):
print(f" - {name}")
# 使用
book = ContactBook()
book.add("张三", "13800138000", "zhangsan@example.com")
book.add("李四", "13900139000")
book.add("王五", "13700137000", "wangwu@example.com")
print()
book.list_all()
print()
book.search("张三")
print()
book.delete("李四")
print()
book.list_all()5.3 案例3:集合在数据分析中的应用
# set_analysis.py
# 学生选课数据
math_students = {"张三", "李四", "王五", "赵六"}
physics_students = {"李四", "王五", "钱七", "孙八"}
chemistry_students = {"王五", "赵六", "孙八", "周九"}
print("数学选课学生:", math_students)
print("物理选课学生:", physics_students)
print("化学选课学生:", chemistry_students)
# 同时选了数学和物理的学生
both_math_physics = math_students & physics_students
print(f"\n同时选数学和物理: {both_math_physics}")
# 选了数学但没选物理的学生
only_math = math_students - physics_students
print(f"只选数学: {only_math}")
# 所有选课的学生
all_students = math_students | physics_students | chemistry_students
print(f"所有选课学生: {all_students}")
print(f"总人数: {len(all_students)}")
# 选了所有三门课的学生
all_three = math_students & physics_students & chemistry_students
print(f"选了所有三门课: {all_three}")
# 只选了一门课的学生
only_one = (math_students ^ physics_students ^ chemistry_students) - all_three
print(f"只选一门课: {only_one}")6. 自测问题
- 字典的键和值有什么要求?
- 如何安全地访问字典中可能不存在的键?
- 集合的主要特点是什么?
- 集合的并集、交集、差集如何表示?
- 什么时候使用字典,什么时候使用集合?
7. 下集预告
下一集我们将学习Python的类与对象入门!
参考资料
- Python官方文档: https://docs.python.org/3/tutorial/datastructures.html
- 《Python编程:从入门到实践》