Python集合知识整理Python集合知识思维导图集合
集合的本质:无序、唯一、可变
1 核心定义
集合是 Python 中一种无序(Unordered)、不重复(Unique)、可变(Mutable)的数据结构。它基于哈希表实现,因此查找、插入、删除操作的平均时间复杂度都是 O(1)。
# 定义集合# 字面量语法,特别注意:空{}是字典哦# {1, 2, 3, 4}s1 = {1, 2, 2, 3, 3, 4}print(s1)# 从可迭代对象中创建 # {1, 2, 3, 4}s2 = set([1, 2, 3, 3, 4])print(s2)# 创建空集合,必须加上set(),不能用{}# set()s3 = set()print(s3)# 自动去重,按照约定 唯一的特点 自动去重# {'e', 'o', 'h', 'l'}s4 = set("hello")print(s4)
2 集合的特点
- 无序性:一个集合中,每个元素的地位都是相同的,元素之间是无序的。
- 互异性:一个集合中,任何两个元素都是不相同的,即元素在集合中只能出现一次。
- 确定性:给定一个集合和一个任意元素,该元素要么属这个集合,要么不属于这个集合,二者必居其一,不允许有模棱两可的情况出现。
Python 程序中的集合跟数学上的集合没有什么本质区别,需要强调的是上面所说的无序性和互异性。无序性说明集合中的元素并不像列中的元素那样存在某种次序,可以通过索引运算就能访问任意元素,集合并不支持索引运算。另外,集合的互异性决定了集合中不能有重复元素,这一点也是集合区别于列表的地方,我们无法将重复的元素添加到一个集合中。集合类型必然是支持in和not in成员运算的,这样就可以确定一个元素是否属于集合,也就是上面所说的集合的确定性。集合的成员运算在性能上要优于列表的成员运算。
3 创建集合
- 字面量语法:也就是
{},其中{}中至少要有一个元素,因为{}中没有元素,则是集合 - 内置函数
set创建:set(),set并不是一个函数,而是创建集合对象的构造器
集合中的元素必须是hashable类型,所谓hashable类型指的是能够计算出哈希码的数据类型,通常不可变类型都是hashable类型,如整数(int)、浮点小数(float)、布尔值(bool)、字符串(str)、元组(tuple)等。可变类型都不是hashable类型,因为可变类型无法计算出确定的哈希码,所以它们不能放到集合中。例如:我们不能将列表作为集合中的元素;同理,由于集合本身也是可变类型,所以集合也不能作为集合中的元素。我们可以创建出嵌套列表(列表的元素也是列表),但是我们不能创建出嵌套的集合,会报错:TypeError: unhashable type: 'set'。
hashable(可哈希):不严谨但是易懂的解释:一个对象在生命周期内,如果保持不变,就是hashable(可哈希);在Python中,集合(set)、列表(list)、字典(dictionary)都是可变的,比如可以通过list.append(),set.remove(),dict['key'] = value对其进行修改,,所以它们都是不可哈希的;而tuple和string是不可变的,只可以做复制或者切片等操作,所以它们就是可哈希的。
# ✅ 合法元素:不可变类型valid_set = {1, 2.5, "hello", (1, 2), True, frozenset({1, 2})}# ❌ 非法元素:可变类型# invalid_set = {[1, 2], {"a": 1}} # TypeError: unhashable type: 'list'
4 与列表、字段的区别
5 集合操作:数学集合的完美实现
5.1 基础操作
也就是增(add()......)、删(remove()......)、查(in、not in)
s = {1, 2, 3}# 增s.add(4) # 添加单个元素,O(1)s.update([5, 6]) # 添加多个元素(并集更新),等价于 s |= {5,6}s |= {7, 8} # 运算符形式# 删s.remove(3) # 元素不存在则抛 KeyErrors.discard(10) # 元素不存在不报错(安全删除)s.pop() # 随机删除并返回一个元素(集合无序!)s.clear() # 清空# 查3in s # 成员检测,O(1)len(s) # 元素个数
5.2 数学的四种核心操作
- 并集: A | B
- 交集:A & B
- 差集:A - B
- 对称差集:A ^ B
A = {1, 2, 3, 4}B = {3, 4, 5, 6}# 1. 并集(Union):A ∪ B → {1,2,3,4,5,6}A | BA.union(B)A.update(B) # 原地修改# 2. 交集(Intersection):A ∩ B → {3,4}A & BA.intersection(B)A.intersection_update(B) # 原地修改:A = A ∩ B# 3. 差集(Difference):A - B → {1,2}(在A中但不在B中)A - BA.difference(B)A.difference_update(B)# 4. 对称差集(Symmetric Difference):A △ B → {1,2,5,6}# 即 (A-B) ∪ (B-A),异或逻辑A ^ BA.symmetric_difference(B)A.symmetric_difference_update(B)
5.3 关系判断
- 子集:
⊆ 等价于 <=等价于A.issubset(B),<(真子集不包含) - 超集:
⊇等价于>=等价于B.issuperset(A),>真超集 - 不相交:
A = {1, 2}B = {1, 2, 3, 4}A.issubset(B) # A ⊆ B ? → TrueA <= B # 同上A < B # A ⊂ B(真子集,A ≠ B)B.issuperset(A) # B ⊇ A ? → TrueB >= A # 同上B > A # B ⊃ A(真超集)C = {5, 6}A.isdisjoint(C) # A ∩ C = ∅ ? → True(不相交)
issubset、issuperset得到的结果是布尔类型。
6 不可变集合
6.1 为什么需要不可变集合
frozenset 是集合的不可变版本,一旦创建就不能修改。它的核心价值在于:
- 可作为字典的键(因为可哈希)
- 可作为其他集合的元素(因为可哈希)
- 保证数据不被意外修改(类似 tuple vs list)
fs = frozenset([1, 2, 3])# ❌ 所有修改操作都被禁止# fs.add(4) # AttributeError# fs.remove(1) # AttributeError# ✅ 但查询和数学运算完全可用3in fs # Truefs | {4, 5} # frozenset({1,2,3,4,5}) → 返回新的 frozenset# ✅ 作为字典键data = {frozenset({1, 2}): "value"}# ✅ 作为集合元素nested = {frozenset({1, 2}), frozenset({3, 4})}
6.2 set vs frozenset对比
7 总结
什么时候用集合?
Python 中的集合类型是一种无序容器,不允许有重复运算,由于底层使用了哈希存储,集合中的元素必须是hashable类型。集合与列表最大的区别在于集合中的元素没有顺序、所以不能够通过索引运算访问元素、但是集合可以执行交集、并集、差集等二元运算,也可以通过关系运算符检查两个集合是否存在超集、子集等关系。