跳到主要内容

Python 集合操作

什么是集合?

集合(set)是Python中的一种无序、可变的数据结构,用于存储唯一的元素。集合中的元素不能重复,并且没有特定的顺序。Python集合基于数学中的集合理论,支持并集、交集、差集等运算。

集合的特点

  • 无序性:集合中的元素没有固定顺序
  • 唯一性:集合中不允许有重复元素
  • 可变性:可以添加或删除元素(使用set类型)
  • 不可索引:不能通过索引访问元素
不可变集合

Python还提供了不可变集合类型frozenset,创建后不能修改其内容。

创建集合

使用花括号

python
# 创建一个包含多个元素的集合
fruits = {"apple", "banana", "cherry", "apple"}
print(fruits) # 重复的元素会被自动删除

输出:

{'apple', 'banana', 'cherry'}

使用set()函数

python
# 从其他可迭代对象创建集合
numbers = set([1, 2, 3, 2, 1])
print(numbers)

# 创建空集合(不能用{}创建空集合,那会创建空字典)
empty_set = set()
print(type(empty_set))
print(type({})) # 这是一个空字典,不是空集合

输出:

{1, 2, 3}
<class 'set'>
<class 'dict'>

基本集合操作

添加元素

python
colors = {"red", "blue"}
colors.add("green") # 添加单个元素
print(colors)

colors.update(["yellow", "orange"]) # 添加多个元素
print(colors)

输出:

{'red', 'blue', 'green'}
{'red', 'blue', 'green', 'yellow', 'orange'}

删除元素

python
fruits = {"apple", "banana", "cherry"}

# remove()方法 - 如果元素不存在会引发KeyError
fruits.remove("banana")
print(fruits)

# discard()方法 - 如果元素不存在不会引发错误
fruits.discard("orange") # 不存在,但不会报错
print(fruits)

# pop()方法 - 随机删除并返回一个元素
popped_item = fruits.pop()
print(f"移除的元素: {popped_item}")
print(fruits)

# clear()方法 - 清空集合
fruits.clear()
print(fruits)

输出:

{'apple', 'cherry'}
{'apple', 'cherry'}
移除的元素: cherry # 可能会不同,因为集合是无序的
{'apple'}
set()

集合运算

Python集合支持数学集合论中的各种操作,这也是集合数据结构最强大的特性。

交集操作

交集包含同时存在于两个集合中的元素。

python
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}

# 使用intersection()方法
intersection_result = set1.intersection(set2)
print(intersection_result)

# 使用&运算符
intersection_result2 = set1 & set2
print(intersection_result2)

输出:

{4, 5}
{4, 5}

并集操作

并集包含两个集合中的所有元素(去重)。

python
# 使用union()方法
union_result = set1.union(set2)
print(union_result)

# 使用|运算符
union_result2 = set1 | set2
print(union_result2)

输出:

{1, 2, 3, 4, 5, 6, 7, 8}
{1, 2, 3, 4, 5, 6, 7, 8}

差集操作

差集包含存在于第一个集合但不存在于第二个集合的元素。

python
# 使用difference()方法
difference_result = set1.difference(set2)
print(difference_result)

# 使用-运算符
difference_result2 = set1 - set2
print(difference_result2)

输出:

{1, 2, 3}
{1, 2, 3}

对称差集操作

对称差集包含仅在其中一个集合中存在的元素。

python
# 使用symmetric_difference()方法
symmetric_difference = set1.symmetric_difference(set2)
print(symmetric_difference)

# 使用^运算符
symmetric_difference2 = set1 ^ set2
print(symmetric_difference2)

输出:

{1, 2, 3, 6, 7, 8}
{1, 2, 3, 6, 7, 8}

集合关系判断

子集和超集

python
set_a = {1, 2, 3}
set_b = {1, 2, 3, 4, 5}

# 判断子集
print(set_a.issubset(set_b)) # set_a是否是set_b的子集
print(set_a <= set_b) # 使用运算符

# 判断超集
print(set_b.issuperset(set_a)) # set_b是否是set_a的超集
print(set_b >= set_a) # 使用运算符

输出:

True
True
True
True

相等和不相交

python
set_c = {1, 2, 3}
set_d = {4, 5, 6}

# 判断相等
print(set_a == set_c) # 两个集合是否相等

# 判断是否不相交
print(set_a.isdisjoint(set_d)) # 两个集合是否没有共同元素

输出:

True
True

不可变集合(frozenset)

如果你需要一个不可变的集合(例如用作字典的键),可以使用frozenset

python
# 创建frozenset
immutable_set = frozenset([1, 2, 3, 2])
print(immutable_set)

# 尝试修改frozenset会抛出错误
try:
immutable_set.add(4)
except AttributeError as e:
print(f"错误: {e}")

# 可以用作字典的键
set_dict = {immutable_set: "这是一个不可变集合"}
print(set_dict)

输出:

frozenset({1, 2, 3})
错误: 'frozenset' object has no attribute 'add'
{frozenset({1, 2, 3}): '这是一个不可变集合'}

实际应用场景

去除重复元素

集合最常见的用途之一是从序列中删除重复项。

python
# 去除列表中的重复项
numbers_list = [1, 2, 2, 3, 3, 3, 4, 4, 5]
unique_numbers = list(set(numbers_list))
print(unique_numbers)

输出:

[1, 2, 3, 4, 5]

成员检测

集合提供非常高效的成员检测操作。

python
# 在大型集合中检测成员
large_set = set(range(10000))
print(5000 in large_set) # 非常快速

输出:

True

数据分析案例

python
# 假设我们有两个电子商务网站的用户ID
site_a_users = {101, 102, 103, 105, 107, 109}
site_b_users = {102, 104, 106, 107, 108}

# 同时在两个网站上注册的用户
users_on_both_sites = site_a_users.intersection(site_b_users)
print(f"在两个网站都注册的用户ID: {users_on_both_sites}")

# 只在网站A注册的用户
only_site_a_users = site_a_users - site_b_users
print(f"只在网站A注册的用户ID: {only_site_a_users}")

# 在任一网站注册的所有用户
all_users = site_a_users.union(site_b_users)
print(f"所有注册用户的总数: {len(all_users)}")

输出:

在两个网站都注册的用户ID: {102, 107}
只在网站A注册的用户ID: {101, 103, 105, 109}
所有注册用户的总数: 9

集合在数学问题中的应用

python
def sieve_of_eratosthenes(n):
"""使用埃拉托斯特尼筛法找出小于n的所有质数"""
numbers = set(range(2, n + 1))
primes = set()

while numbers:
p = min(numbers)
primes.add(p)
numbers.difference_update(set(range(p, n + 1, p)))

return primes

primes_under_100 = sieve_of_eratosthenes(100)
print(f"100以内的质数: {sorted(primes_under_100)}")

输出:

100以内的质数: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

集合的性能考虑

集合提供了高效的操作,特别是在检查元素存在性和去除重复元素方面。下面是集合操作的时间复杂度:

总结

Python集合是一种强大的数据结构,非常适合需要唯一元素、高效查找和集合论操作的场景。主要特点包括:

  1. 集合中的元素是唯一
  2. 集合是无序
  3. 支持标准的集合操作(并集、交集、差集等)
  4. 提供高效的成员检测
  5. 非常适合去重和比较数据集合

集合操作在数据科学、Web开发和各种算法中有广泛应用,是Python编程的重要工具。

练习题

  1. 编写一个函数,找出两个字符串的相同字符(区分大小写)。
  2. 使用集合操作找出列表中只出现一次的元素。
  3. 实现一个简单的通讯录系统,使用集合来跟踪"所有联系人"、"家人"和"朋友"等分组。
  4. 编写一个程序,判断一个单词是否是另一个单词的变位词(包含相同的字符,但顺序不同)。

进一步阅读

  • Python官方文档:集合类型
  • 学习Python中的其他数据结构,如列表、元组和字典
  • 探索更复杂的集合应用,如在图论中表示顶点和边