Skip to content

Python 集合

集合是 Python 中的一种无序、不重复的数据结构,用于存储唯一的元素。本章节将详细介绍 Python 中的集合及其操作。

集合的创建

可以使用花括号 {}set() 函数来创建集合。

示例:

python
# 集合的创建

# 使用花括号创建集合
set1 = {1, 2, 3, 4, 5}
print(set1)  # 输出:{1, 2, 3, 4, 5}

# 创建空集合(注意:不能使用 {},因为 {} 创建的是空字典)
set2 = set()
print(set2)  # 输出:set()
print(type(set2))  # 输出:<class 'set'>

# 创建包含不同类型元素的集合
set3 = {1, "hello", 3.14, True}
print(set3)  # 输出:{1, 'hello', 3.14}

# 注意:True 会被视为 1,所以不会重复
set4 = {1, True}
print(set4)  # 输出:{1}

# 使用 set() 函数创建集合
set5 = set([1, 2, 3, 4, 5])
print(set5)  # 输出:{1, 2, 3, 4, 5}

# 使用 set() 函数将字符串转换为集合
set6 = set("hello")
print(set6)  # 输出:{'h', 'e', 'l', 'o'}(注意:重复的 'l' 只保留一个)

# 使用 set() 函数将元组转换为集合
set7 = set((1, 2, 3, 4, 5))
print(set7)  # 输出:{1, 2, 3, 4, 5}

# 使用集合推导式创建集合
set8 = {i for i in range(10) if i % 2 == 0}
print(set8)  # 输出:{0, 2, 4, 6, 8}

集合的特点

集合具有以下特点:

  1. 无序性:集合中的元素没有固定的顺序,每次打印可能会不同。
  2. 唯一性:集合中的元素是唯一的,不会重复。
  3. 可变性:集合是可变的,可以添加或删除元素。
  4. 不可哈希性:集合中的元素必须是可哈希的(不可变的),例如数字、字符串、元组等,不能包含列表、字典等可变类型。

示例:

python
# 集合的特点

# 无序性
set1 = {3, 1, 4, 1, 5, 9, 2, 6}
print(set1)  # 输出:{1, 2, 3, 4, 5, 6, 9}(顺序可能不同)

# 唯一性
set2 = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4}
print(set2)  # 输出:{1, 2, 3, 4}(重复元素被自动去重)

# 不可哈希性(尝试添加可变类型会引发错误)
# set3 = {1, 2, [3, 4]}  # TypeError: unhashable type: 'list'
# set4 = {1, 2, {"a": 1}}  # TypeError: unhashable type: 'dict'

# 可以添加元组(不可变类型)
set5 = {1, 2, (3, 4)}
print(set5)  # 输出:{1, 2, (3, 4)}

集合的方法

Python 提供了许多内置的集合方法,用于操作集合。

添加元素

方法描述示例
add(element)向集合中添加一个元素set.add(6)
update(iterable)向集合中添加多个元素(可迭代对象)set.update([6, 7, 8])

示例:

python
# 添加元素
set1 = {1, 2, 3, 4, 5}

# add() 方法
print("使用 add() 方法添加元素:")
set1.add(6)
print(set1)  # 输出:{1, 2, 3, 4, 5, 6}

# 添加已存在的元素(不会有变化)
set1.add(3)
print(set1)  # 输出:{1, 2, 3, 4, 5, 6}(无变化)

# update() 方法
print("\n使用 update() 方法添加元素:")
set1.update([7, 8, 9])
print(set1)  # 输出:{1, 2, 3, 4, 5, 6, 7, 8, 9}

# 使用字符串更新
set1.update("abc")
print(set1)  # 输出:{1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c'}

# 使用元组更新
set1.update((10, 11))
print(set1)  # 输出:{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 'a', 'b', 'c'}

删除元素

方法描述示例
remove(element)从集合中删除一个元素,如果元素不存在则引发错误set.remove(3)
discard(element)从集合中删除一个元素,如果元素不存在则不做任何操作set.discard(3)
pop()随机删除并返回集合中的一个元素set.pop()
clear()清空集合set.clear()

示例:

python
# 删除元素
set1 = {1, 2, 3, 4, 5, 6, 7, 8, 9}

# remove() 方法
print("使用 remove() 方法删除元素:")
set1.remove(3)
print(set1)  # 输出:{1, 2, 4, 5, 6, 7, 8, 9}

# 尝试删除不存在的元素会引发错误
# set1.remove(10)  # KeyError: 10

# discard() 方法
print("\n使用 discard() 方法删除元素:")
set1.discard(4)
print(set1)  # 输出:{1, 2, 5, 6, 7, 8, 9}

# 删除不存在的元素(无变化)
set1.discard(10)
print(set1)  # 输出:{1, 2, 5, 6, 7, 8, 9}(无变化)

# pop() 方法
print("\n使用 pop() 方法删除元素:")
popped = set1.pop()
print(f"被删除的元素:{popped}")  # 输出:被删除的元素:1(随机)
print(set1)  # 输出:{2, 5, 6, 7, 8, 9}

# clear() 方法
print("\n使用 clear() 方法清空集合:")
set1.clear()
print(set1)  # 输出:set()

集合的运算

方法描述示例
union(other) 或 ``返回两个集合的并集
intersection(other)&返回两个集合的交集set1.intersection(set2)set1 & set2
difference(other)-返回两个集合的差集set1.difference(set2)set1 - set2
symmetric_difference(other)^返回两个集合的对称差集set1.symmetric_difference(set2)set1 ^ set2
issubset(other)<=检查一个集合是否是另一个集合的子集set1.issubset(set2)set1 <= set2
issuperset(other)>=检查一个集合是否是另一个集合的超集set1.issuperset(set2)set1 >= set2
isdisjoint(other)检查两个集合是否不相交(没有共同元素)set1.isdisjoint(set2)

示例:

python
# 集合的运算
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}

# 并集
print("并集:")
print(set1.union(set2))  # 输出:{1, 2, 3, 4, 5, 6, 7, 8}
print(set1 | set2)  # 输出:{1, 2, 3, 4, 5, 6, 7, 8}

# 交集
print("\n交集:")
print(set1.intersection(set2))  # 输出:{4, 5}
print(set1 & set2)  # 输出:{4, 5}

# 差集
print("\n差集:")
print(set1.difference(set2))  # 输出:{1, 2, 3}(set1 中有但 set2 中没有的元素)
print(set1 - set2)  # 输出:{1, 2, 3}
print(set2.difference(set1))  # 输出:{6, 7, 8}(set2 中有但 set1 中没有的元素)
print(set2 - set1)  # 输出:{6, 7, 8}

# 对称差集
print("\n对称差集:")
print(set1.symmetric_difference(set2))  # 输出:{1, 2, 3, 6, 7, 8}(两个集合中不同时存在的元素)
print(set1 ^ set2)  # 输出:{1, 2, 3, 6, 7, 8}

# 子集
set3 = {1, 2, 3}
print("\n子集:")
print(set3.issubset(set1))  # 输出:True(set3 是 set1 的子集)
print(set3 <= set1)  # 输出:True
print(set1.issubset(set3))  # 输出:False(set1 不是 set3 的子集)
print(set1 <= set3)  # 输出:False

# 超集
print("\n超集:")
print(set1.issuperset(set3))  # 输出:True(set1 是 set3 的超集)
print(set1 >= set3)  # 输出:True
print(set3.issuperset(set1))  # 输出:False(set3 不是 set1 的超集)
print(set3 >= set1)  # 输出:False

# 不相交
set4 = {9, 10}
print("\n不相交:")
print(set1.isdisjoint(set4))  # 输出:True(set1 和 set4 没有共同元素)
print(set1.isdisjoint(set2))  # 输出:False(set1 和 set2 有共同元素)

集合的修改运算

方法描述示例
update(other) 或 `=`更新集合为自身与另一个集合的并集
intersection_update(other)&=更新集合为自身与另一个集合的交集set1.intersection_update(set2)set1 &= set2
difference_update(other)-=更新集合为自身与另一个集合的差集set1.difference_update(set2)set1 -= set2
symmetric_difference_update(other)^=更新集合为自身与另一个集合的对称差集set1.symmetric_difference_update(set2)set1 ^= set2

示例:

python
# 集合的修改运算

# update() 方法
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
print("使用 update() 方法:")
print(f"更新前:set1 = {set1}")
set1.update(set2)
print(f"更新后:set1 = {set1}")  # 输出:set1 = {1, 2, 3, 4, 5, 6, 7, 8}

# intersection_update() 方法
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
print("\n使用 intersection_update() 方法:")
print(f"更新前:set1 = {set1}")
set1.intersection_update(set2)
print(f"更新后:set1 = {set1}")  # 输出:set1 = {4, 5}

# difference_update() 方法
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
print("\n使用 difference_update() 方法:")
print(f"更新前:set1 = {set1}")
set1.difference_update(set2)
print(f"更新后:set1 = {set1}")  # 输出:set1 = {1, 2, 3}

# symmetric_difference_update() 方法
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
print("\n使用 symmetric_difference_update() 方法:")
print(f"更新前:set1 = {set1}")
set1.symmetric_difference_update(set2)
print(f"更新后:set1 = {set1}")  # 输出:set1 = {1, 2, 3, 6, 7, 8}

其他方法

方法描述示例
copy()返回集合的浅拷贝set.copy()
len(set)返回集合的长度len(set)
in检查元素是否在集合中5 in set
not in检查元素是否不在集合中10 not in set

示例:

python
# 其他方法
set1 = {1, 2, 3, 4, 5}

# copy() 方法
print("使用 copy() 方法创建拷贝:")
set2 = set1.copy()
print(set2)  # 输出:{1, 2, 3, 4, 5}

# 修改原集合,不影响拷贝
set1.add(6)
print(f"原集合:{set1}")  # 输出:原集合:{1, 2, 3, 4, 5, 6}
print(f"拷贝集合:{set2}")  # 输出:拷贝集合:{1, 2, 3, 4, 5}

# len() 函数
print(f"集合的长度:{len(set1)}")  # 输出:集合的长度:6

# in 运算符
print(f"3 在集合中:{3 in set1}")  # 输出:3 在集合中:True
print(f"10 在集合中:{10 in set1}")  # 输出:10 在集合中:False

# not in 运算符
print(f"10 不在集合中:{10 not in set1}")  # 输出:10 不在集合中:True
print(f"3 不在集合中:{3 not in set1}")  # 输出:3 不在集合中:False

集合的遍历

可以使用 for 循环来遍历集合中的元素。

示例:

python
# 集合的遍历
set1 = {1, 2, 3, 4, 5}

# 遍历元素
print("遍历元素:")
for element in set1:
    print(element)

# 注意:集合是无序的,所以遍历顺序可能不同

# 使用 enumerate() 遍历索引和元素
print("\n遍历索引和元素:")
for index, element in enumerate(set1):
    print(f"索引 {index}: {element}")

# 使用 sorted() 函数按顺序遍历
print("\n按顺序遍历:")
for element in sorted(set1):
    print(element)

集合推导式

集合推导式是一种简洁的创建集合的方法,语法为 {expression for item in iterable if condition}

示例:

python
# 集合推导式

# 创建一个包含 0 到 9 的偶数的集合
set1 = {i for i in range(10) if i % 2 == 0}
print(set1)  # 输出:{0, 2, 4, 6, 8}

# 创建一个包含字符串长度的集合
words = ["hello", "world", "python", "programming"]
set2 = {len(word) for word in words}
print(set2)  # 输出:{5, 6, 11}

# 创建一个包含数字平方的集合
set3 = {i**2 for i in range(10) if i % 3 == 0}
print(set3)  # 输出:{0, 9, 36, 81}

# 从列表中创建集合(去重)
list_with_duplicates = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
set4 = {x for x in list_with_duplicates}
print(set4)  # 输出:{1, 2, 3, 4}

# 嵌套集合推导式
set5 = {i + j for i in range(3) for j in range(2)}
print(set5)  # 输出:{0, 1, 2, 3}

集合的应用场景

集合的特性使其在以下场景中特别有用:

  1. 去重:快速去除列表或其他可迭代对象中的重复元素。
  2. 成员检查:快速检查元素是否存在于集合中(比列表快)。
  3. 集合运算:快速执行并集、交集、差集等集合运算。
  4. 数据过滤:根据条件过滤数据。
  5. 唯一性保证:确保数据的唯一性。

示例:

python
# 集合的应用场景

# 去重
print("使用集合去重:")
list_with_duplicates = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique_list = list(set(list_with_duplicates))
print(f"原列表:{list_with_duplicates}")
print(f"去重后:{unique_list}")  # 输出:去重后:[1, 2, 3, 4](顺序可能不同)

# 成员检查
print("\n使用集合进行成员检查:")
# 对于大型数据集,集合的成员检查比列表快
large_list = list(range(1000000))
large_set = set(large_list)

# 检查元素是否存在
import time

start = time.time()
999999 in large_list
end = time.time()
print(f"列表成员检查时间:{end - start:.6f} 秒")

start = time.time()
999999 in large_set
end = time.time()
print(f"集合成员检查时间:{end - start:.6f} 秒")

# 集合运算
print("\n使用集合进行运算:")
# 假设有两个用户组
group1 = {"user1", "user2", "user3", "user4"}
group2 = {"user3", "user4", "user5", "user6"}

# 找出同时在两个组中的用户
common_users = group1 & group2
print(f"同时在两个组中的用户:{common_users}")  # 输出:同时在两个组中的用户:{'user3', 'user4'}

# 找出只在 group1 中的用户
exclusive_group1 = group1 - group2
print(f"只在 group1 中的用户:{exclusive_group1}")  # 输出:只在 group1 中的用户:{'user1', 'user2'}

# 找出只在 group2 中的用户
exclusive_group2 = group2 - group1
print(f"只在 group2 中的用户:{exclusive_group2}")  # 输出:只在 group2 中的用户:{'user5', 'user6'}

# 找出所有用户
all_users = group1 | group2
print(f"所有用户:{all_users}")  # 输出:所有用户:{'user1', 'user2', 'user3', 'user4', 'user5', 'user6'}

# 数据过滤
print("\n使用集合过滤数据:")
# 假设有一个词汇表和一个禁用词表
vocabulary = {"apple", "banana", "cherry", "date", "elderberry"}
banned_words = {"cherry", "date"}

# 过滤掉禁用词
filtered_vocabulary = vocabulary - banned_words
print(f"过滤后的词汇表:{filtered_vocabulary}")  # 输出:过滤后的词汇表:{'apple', 'banana', 'elderberry'}

冻结集合(frozenset)

冻结集合是一种不可变的集合,创建后不能修改。可以使用 frozenset() 函数来创建冻结集合。

示例:

python
# 冻结集合

# 创建冻结集合
frozen_set = frozenset({1, 2, 3, 4, 5})
print(frozen_set)  # 输出:frozenset({1, 2, 3, 4, 5})
print(type(frozen_set))  # 输出:<class 'frozenset'>

# 尝试修改冻结集合会引发错误
# frozen_set.add(6)  # AttributeError: 'frozenset' object has no attribute 'add'
# frozen_set.remove(1)  # AttributeError: 'frozenset' object has no attribute 'remove'

# 冻结集合的方法(只能使用不修改集合的方法)
print(f"集合的长度:{len(frozen_set)}")  # 输出:集合的长度:5
print(f"3 在集合中:{3 in frozen_set}")  # 输出:3 在集合中:True
print(f"6 在集合中:{6 in frozen_set}")  # 输出:6 在集合中:False

# 冻结集合的运算
frozen_set2 = frozenset({4, 5, 6, 7, 8})
print(f"并集:{frozen_set.union(frozen_set2)}")  # 输出:并集:frozenset({1, 2, 3, 4, 5, 6, 7, 8})
print(f"交集:{frozen_set.intersection(frozen_set2)}")  # 输出:交集:frozenset({4, 5})
print(f"差集:{frozen_set.difference(frozen_set2)}")  # 输出:差集:frozenset({1, 2, 3})

# 冻结集合的应用场景
print("\n冻结集合的应用场景:")
# 作为字典的键
dict_with_frozen_set = {frozen_set: "value"}
print(dict_with_frozen_set)  # 输出:{frozenset({1, 2, 3, 4, 5}): 'value'}

# 作为集合的元素
set_with_frozen_set = {frozen_set, frozenset({6, 7, 8})}
print(set_with_frozen_set)  # 输出:{frozenset({1, 2, 3, 4, 5}), frozenset({6, 7, 8})}

总结

Python 中的集合是一种非常实用的数据结构,提供了丰富的方法来操作元素。本章节介绍了集合的创建、特点、方法、运算、遍历、推导式、应用场景以及冻结集合等内容。掌握集合的使用对于编写 Python 代码非常重要。