python - 集合

267 阅读4分钟

在 Python 中,集合(Set)  是一种无序、可变的数据结构,用于存储唯一的(不可重复的)元素。集合支持高效的成员检测、并集、交集等数学运算。以下是 Python 集合的详细用法和示例:


1. 创建集合

方式 1:使用花括号 {}

# 空集合必须用 set() 创建,{} 表示空字典
empty_set = set()
 
# 带初始值的集合
numbers = {1, 2, 3, 4, 5}
fruits = {"apple", "banana", "orange"}

方式 2:使用 set() 构造函数

# 从列表创建集合(自动去重)
unique_numbers = set([1, 2, 2, 3, 4, 4])
print(unique_numbers)  # 输出: {1, 2, 3, 4}
 
# 从字符串创建集合(拆分字符并去重)
letters = set("hello")
print(letters)  # 输出: {'h', 'e', 'l', 'o'}(顺序可能不同)

2. 集合的特性

  • 唯一性:集合会自动去重,不允许重复元素。
  • 无序性:集合中的元素没有固定顺序(Python 3.7+ 后仍不保证顺序)。
  • 可变性:集合是可变的(可添加/删除元素),但元素必须是不可变类型(如 intstrtuple,不能是 list 或 dict)。

3. 集合的基本操作

添加元素

fruits = {"apple", "banana"}
fruits.add("orange")  # 添加单个元素
print(fruits)  # 输出: {'apple', 'banana', 'orange'}

更新集合(批量添加)

fruits.update(["grape", "mango"])  # 添加多个元素
print(fruits)  # 输出: {'apple', 'banana', 'orange', 'grape', 'mango'}

删除元素

fruits.remove("apple")  # 删除指定元素(如果不存在则报错 KeyError)
fruits.discard("banana")  # 删除元素(不存在也不会报错)
popped_item = fruits.pop()  # 随机删除并返回一个元素

清空集合

fruits.clear()  # 清空集合
print(fruits)  # 输出: set()

4. 集合的数学运算

并集(Union)

set1 = {1, 2, 3}
set2 = {3, 4, 5}
print(set1 | set2)  # 输出: {1, 2, 3, 4, 5}
print(set1.union(set2))  # 等效写法

交集(Intersection)

print(set1 & set2)  # 输出: {3}
print(set1.intersection(set2))  # 等效写法

差集(Difference)

print(set1 - set2)  # 输出: {1, 2}(set1 有而 set2 没有的元素)
print(set1.difference(set2))  # 等效写法

对称差集(Symmetric Difference)

print(set1 ^ set2)  # 输出: {1, 2, 4, 5}(仅在其中一个集合中的元素)
print(set1.symmetric_difference(set2))  # 等效写法

5. 集合的比较运算

set_a = {1, 2, 3}
set_b = {1, 2, 3, 4}
 
# 子集检查
print(set_a <= set_b)  # True(set_a 是 set_b 的子集)
print(set_a.issubset(set_b))  # 等效写法
 
# 超集检查
print(set_b >= set_a)  # True(set_b 是 set_a 的超集)
print(set_b.issuperset(set_a))  # 等效写法
 
# 严格子集/超集(不等于)
print(set_a < set_b)  # True
print(set_b > set_a)  # True

6. 集合推导式(Set Comprehension)

# 生成平方数集合
squares = {x**2 for x in range(5)}
print(squares)  # 输出: {0, 1, 4, 9, 16}
 
# 过滤偶数
even_numbers = {x for x in range(10) if x % 2 == 0}
print(even_numbers)  # 输出: {0, 2, 4, 6, 8}

7. 冻结集合(Frozen Set)

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

frozen = frozenset([1, 2, 3])
print(frozen)  # 输出: frozenset({1, 2, 3})
 
# frozenset 可以作为字典的键
d = {frozenset([1, 2]): "value"}

8. 集合的常见应用

去重

lst = [1, 2, 2, 3, 4, 4, 5]
unique_lst = list(set(lst))
print(unique_lst)  # 输出: [1, 2, 3, 4, 5]

快速成员检测

if "apple" in fruits:
    print("Found!")

统计唯一值

words = ["hello", "world", "hello", "python"]
unique_words = set(words)
print(len(unique_words))  # 输出: 3

9. 注意事项

  1. 集合是无序的,不能通过索引访问元素。

  2. 集合的元素必须是不可变类型(如 intstrtuple),不能包含 list 或 dict

    invalid_set = {[1, 2], 3}  # TypeError: unhashable type: 'list'
    
  3. 空集合必须用 set() 创建{} 表示空字典。


集合方法

方法作用示例
add(elem)添加单个元素s.add(1)
update(iterable)添加多个元素s.update([1, 2, 3])
remove(elem)删除元素(不存在则报错)s.remove(1)
discard(elem)删除元素(不存在不报错)s.discard(1)
pop()随机删除并返回一个元素s.pop()
clear()清空集合s.clear()
union(set2) / |并集s1 | s2
intersection(set2) / &交集s1 & s2
difference(set2) / -差集s1 - s2
symmetric_difference(set2) / ^对称差集s1 ^ s2
issubset(set2) / <=子集检查s1 <= s2
issuperset(set2) / >=超集检查s1 >= s2
isdisjoint(set2)无交集检查s1.isdisjoint(s2)
copy()浅拷贝集合s.copy()

总结

  • 集合适用于需要唯一值、高效成员检测或数学运算(如并集、交集)的场景。
  • 使用 add()remove()update() 等方法操作集合。
  • 通过 |&-^ 等符号或 union()intersection() 等方法进行集合运算。

如果需要不可变集合,可以使用 frozenset