使用dict和set

字典(dict)基础

Python中的字典(dict)是一种高效的键值对(key-value)数据结构,在其他语言中也被称为哈希表或映射(map)。

字典的基本使用

# 创建字典
student_scores = {'Michael': 95, 'Bob': 75, 'Tracy': 85}

# 访问元素
print(student_scores['Michael'])  # 输出: 95

# 添加/修改元素
student_scores['Adam'] = 67
student_scores['Bob'] = 80  # 修改Bob的分数

# 删除元素
removed_score = student_scores.pop('Bob')

字典的高效性原理

字典之所以能快速查找,是因为它使用了哈希表(Hash Table)实现:

  1. 通过哈希函数计算键的哈希值
  2. 根据哈希值直接定位到值的存储位置
  3. 查找时间复杂度接近O(1),不会随着数据量增加而变慢

字典常用操作

# 检查键是否存在
if 'Michael' in student_scores:
    print("Michael exists")

# 安全获取值
score = student_scores.get('Thomas', -1)  # 不存在返回-1

# 获取所有键
keys = student_scores.keys()

# 获取所有值
values = student_scores.values()

# 获取所有键值对
items = student_scores.items()

# 字典推导式
squares = {x: x*x for x in range(5)}

字典的特点

  1. 无序性:Python 3.7+虽然保持插入顺序,但不应依赖此特性
  2. 键唯一性:每个键只能对应一个值
  3. 键不可变性:键必须是不可变类型(字符串、数字、元组等)

集合(set)基础

集合(set)是一种无序且不重复的元素集合,基于哈希表实现。

集合的基本使用

# 创建集合
s = {1, 2, 3}
# 或从列表创建
s = set([1, 2, 3, 2])  # 结果为{1, 2, 3}

# 添加元素
s.add(4)

# 删除元素
s.remove(3)  # 不存在会报错
s.discard(3)  # 安全删除,不存在不报错

# 集合运算
s1 = {1, 2, 3}
s2 = {2, 3, 4}

print(s1 & s2)  # 交集: {2, 3}
print(s1 | s2)  # 并集: {1, 2, 3, 4}
print(s1 - s2)  # 差集: {1}
print(s1 ^ s2)  # 对称差集: {1, 4}

集合的特点

  1. 无序性:元素没有固定顺序
  2. 唯一性:自动去除重复元素
  3. 元素不可变性:只能包含不可变类型

不可变对象与可变对象

可变对象(Mutable)

如列表(list)、字典(dict)、集合(set)等,内容可以修改。

lst = [3, 1, 2]
lst.sort()  # 原地排序
print(lst)  # [1, 2, 3]

不可变对象(Immutable)

如字符串(str)、数字(int, float)、元组(tuple)等,创建后不能修改。

s = "hello"
new_s = s.replace('h', 'H')  # 创建新字符串
print(s)     # "hello" (原字符串不变)
print(new_s) # "Hello"

实际应用建议

  1. 字典使用场景

    • 需要快速查找的键值对数据
    • 数据分组统计
    • 缓存实现
  2. 集合使用场景

    • 去重处理
    • 成员快速检测
    • 集合运算(交集、并集等)
  3. 性能考虑

    • 字典和集合占用更多内存,但查询速度快
    • 列表占用内存少,但查询速度随数据量增加而变慢

常见问题解答

Q: 为什么列表不能作为字典的键或集合的元素?

A: 因为列表是可变的,其哈希值可能改变,这会破坏字典和集合的内部结构。如果需要使用类似列表的结构作为键,可以使用不可变的元组。

# 可行的元组作为键
d = {(1, 2): "value"}

# 不可行的列表作为键
# d = {[1, 2]: "value"}  # 会报错

Q: Python 3.7+中字典保持插入顺序,这是否意味着字典是有序的?

A: 虽然Python 3.7+中字典会保持插入顺序,但从语言规范角度,字典仍被视为无序结构。如果需要有序字典,应使用collections.OrderedDict