1、什么是集合?
集合是Python中的一种无序、可变、不重复元素的容器类型。它基于数学中的集合概念实现,常用于去重、成员测试和数学运算。
✅ 可变性:可以添加或删除元素
✅ 自动去重:重复元素仅保留一份
✅ 元素要求:必须为可哈希类型(不可变:数字、字符串、元组等)
✅ 无序性:元素没有固定顺序
❌ 不支持:索引访问、切片、包含可变对象(列表/字典/集合)
2. 创建集合
语法1:使用花括号
①. 创建空集合(注意:不能用{}创建空集合,{}创建的是字典)empty_set = set()②. 创建有元素的集合fruits = {"apple", "banana", "cherry"}numbers = {1, 2, 3, 4, 5}print(fruits) # 输出:{'banana', 'apple', 'cherry'}(顺序可能不同)print(type(fruits)) # 输出:<class 'set'>
语法2:使用set()构造函数
①. 从列表创建集合list_to_set = set([1, 2, 2, 3, 3, 4])print(list_to_set) # 输出:{1, 2, 3, 4}(自动去重)②. 从元组创建集合tuple_to_set = set((1, 2, 3, 2, 1))print(tuple_to_set) # 输出:{1, 2, 3}③. 从字符串创建集合(每个字符作为元素)string_to_set = set("hello")print(string_to_set) # 输出:{'e', 'h', 'l', 'o'}
语法3:集合推导式
①. 创建平方数的集合squares = {x**2 for x in range(10)}print(squares) # 输出:{0, 1, 4, 9, 16, 25, 36, 49, 64, 81}②. 带条件的集合推导式even_squares = {x**2 for x in range(10) if x % 2 == 0}print(even_squares) # 输出:{0, 4, 16, 36, 64}
注意:集合元素必须是可哈希的
①. 正确的:使用不可变类型valid_set = {1, 2.5, "hello", (1, 2, 3)}print(valid_set) # 输出正常②. 错误的:尝试使用可变类型try: invalid_set = {[1, 2], [3, 4]} # 列表是可变的,不可哈希except TypeError as e: print(f"错误: {e}") # 输出:错误: unhashable type: 'list'
3. 集合基本操作
添加元素
# 语法:set.add(element)fruits = {"apple", "banana"}fruits.add("orange")print(fruits) # 输出:{'banana', 'orange', 'apple'}# 添加已存在的元素不会有变化fruits.add("apple")print(fruits) # 输出:{'banana', 'orange', 'apple'}(不变)
更新集合(添加多个元素)
# 语法:set.update(iterable)fruits = {"apple", "banana"}fruits.update(["orange", "grape", "apple"])print(fruits) # 输出:{'grape', 'banana', 'orange', 'apple'}可以使用任何可迭代对象:fruits.update(("kiwi", "mango"))print(fruits) # 输出包含新增水果
删除元素
①. 语法1:set.remove(element) - 元素必须存在fruits = {"apple", "banana", "cherry"}fruits.remove("banana")print(fruits) # 输出:{'cherry', 'apple'}try: fruits.remove("orange") # 不存在会报错except KeyError as e: print(f"KeyError: {e}") # 输出:KeyError: 'orange'②. 语法2:set.discard(element) - 元素不存在不会报错fruits.discard("apple")fruits.discard("watermelon") # 不会报错print(fruits) # 输出:{'cherry'}③. 语法3:set.pop() - 随机删除并返回一个元素fruits = {"apple", "banana", "cherry"}removed_item = fruits.pop()print(f"删除了: {removed_item}, 剩余: {fruits}")④. 语法4:set.clear() - 清空集合fruits.clear()print(fruits) # 输出:set()
查询操作
检查元素是否存在:fruits = {"apple", "banana", "cherry"}print("apple" in fruits) # 输出:Trueprint("orange" not in fruits) # 输出:True获取集合长度:print(len(fruits)) # 输出:3
4. 集合运算
并集(Union)
语法1:set1.union(set2) 或 set1 | set2A = {1, 2, 3}B = {3, 4, 5}①. 方法1:使用union()方法union_set = A.union(B)print(union_set) # 输出:{1, 2, 3, 4, 5}②. 方法2:使用|运算符union_set = A | Bprint(union_set) # 输出:{1, 2, 3, 4, 5}③. 多个集合的并集C = {5, 6, 7}multi_union = A.union(B, C)print(multi_union) # 输出:{1, 2, 3, 4, 5, 6, 7}
交集(Intersection)
语法:set1.intersection(set2) 或 set1 & set2A = {1, 2, 3, 4}B = {3, 4, 5, 6}①. 方法1:使用intersection()方法intersection_set = A.intersection(B)print(intersection_set) # 输出:{3, 4}②. 方法2:使用&运算符intersection_set = A & Bprint(intersection_set) # 输出:{3, 4}③. 多个集合的交集C = {4, 5, 6}multi_intersection = A.intersection(B, C)print(multi_intersection) # 输出:{4}
差集(Difference)
语法:set1.difference(set2) 或 set1 - set2A = {1, 2, 3, 4, 5}B = {4, 5, 6, 7}①. 方法1:使用difference()方法difference_set = A.difference(B)print(difference_set) # 输出:{1, 2, 3}②. 方法2:使用-运算符difference_set = A - Bprint(difference_set) # 输出:{1, 2, 3}③. 注意:差集运算顺序很重要difference_set = B - Aprint(difference_set) # 输出:{6, 7}
对称差集(Symmetric Difference)
语法:set1.symmetric_difference(set2) 或 set1 ^ set2A = {1, 2, 3, 4}B = {3, 4, 5, 6}①. 方法1:使用symmetric_difference()方法sym_diff_set = A.symmetric_difference(B)print(sym_diff_set) # 输出:{1, 2, 5, 6}②. 方法2:使用^运算符sym_diff_set = A ^ Bprint(sym_diff_set) # 输出:{1, 2, 5, 6}
集合关系判断
①. 子集判断A = {1, 2, 3}B = {1, 2, 3, 4, 5}语法:set1.issubset(set2) 或 set1 <= set2print(A.issubset(B)) # 输出:Trueprint(A <= B) # 输出:True②. 真子集判断:set1 < set2print(A < B) # 输出:True(A是B的真子集)print(A < A) # 输出:False(集合不是自身的真子集)③. 超集判断语法:set1.issuperset(set2) 或 set1 >= set2print(B.issuperset(A)) # 输出:Trueprint(B >= A) # 输出:True④. 真超集判断:set1 > set2print(B > A) # 输出:True⑤. 相交判断C = {6, 7, 8}print(A.isdisjoint(C)) # 输出:Trueprint(A.isdisjoint(B)) # 输出:False(有交集)
5. 集合的常用方法
复制集合
语法:set.copy()original = {1, 2, 3}copy_set = original.copy()copy_set.add(4)print(original) # 输出:{1, 2, 3}print(copy_set) # 输出:{1, 2, 3, 4}
修改原集合的方法
①. 更新原集合为并集A = {1, 2, 3}B = {3, 4, 5}A.update(B) # 相当于 A |= Bprint(A) # 输出:{1, 2, 3, 4, 5}②. 更新原集合为交集A = {1, 2, 3, 4}B = {3, 4, 5}A.intersection_update(B) # 相当于 A &= Bprint(A) # 输出:{3, 4}③. 更新原集合为差集A = {1, 2, 3, 4}B = {3, 4, 5}A.difference_update(B) # 相当于 A -= Bprint(A) # 输出:{1, 2}④. 更新原集合为对称差集A = {1, 2, 3, 4}B = {3, 4, 5}A.symmetric_difference_update(B) # 相当于 A ^= Bprint(A) # 输出:{1, 2, 5}
冻结集合(frozenset)
①. frozenset是不可变集合frozen = frozenset([1, 2, 3, 2, 1])print(frozen) # 输出:frozenset({1, 2, 3})print(type(frozen)) # 输出:<class 'frozenset'>②. frozenset可以用作字典的键或另一个集合的元素dict_with_frozenset = {frozenset([1, 2]): "value1", frozenset([3, 4]): "value2"}print(dict_with_frozenset) # 输出:{frozenset({1, 2}): 'value1', frozenset({3, 4}): 'value2'}set_of_frozensets = {frozenset([1, 2]), frozenset([3, 4])}print(set_of_frozensets) # 输出:{frozenset({3, 4}), frozenset({1, 2})}
6. 集合的应用示例
示例1:数据去重
①. 从列表中去除重复项numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]unique_numbers = list(set(numbers))print(unique_numbers) # 输出:[1, 2, 3, 4](顺序可能不同)②. 保持原始顺序的去重方法(Python 3.7+)from collections import OrderedDictnumbers = [3, 1, 2, 2, 3, 1, 4]unique_ordered = list(OrderedDict.fromkeys(numbers))print(unique_ordered) # 输出:[3, 1, 2, 4]
示例2:查找共同元素
找出两个列表的共同元素:list1 = [1, 2, 3, 4, 5]list2 = [4, 5, 6, 7, 8]common = set(list1) & set(list2)print(common) # 输出:{4, 5}
7、高频陷阱与避坑指南
❌ 陷阱1:空集合误写为 {}
s = {}print(type(s)) # <class 'dict'> → 逻辑错误根源!
✅ 正确做法:s = set()
❌ 陷阱2:包含不可哈希元素
# set([ [1,2], 3 ]) # TypeError: unhashable type: 'list'
✅ 正确做法:用元组替代
valid = { (1,2), 3 } # {(1, 2), 3}
❌ 陷阱3:依赖集合顺序
s = {3, 1, 2}# print(s[0]) # TypeError: 'set' object is not subscriptable
✅ 正确做法:需顺序时转为列表+排序
sorted_list = sorted(s) # [1, 2, 3]
❌ 陷阱4:浮点数精度问题
s = {0.1 + 0.2, 0.3}print(len(s)) # 输出:2(因0.1+0.2=0.30000000000000004 ≠ 0.3)
✅ 建议:避免浮点数精确比较,或使用decimal模块
8、使用场景:
去除重复元素
快速成员测试
数学集合运算(并集、交集、差集等)
需要唯一元素的场景
9、总结
| |
|---|
| |
| 仅限可哈希类型(数字/字符串/元组),禁止列表/字典/集合 |
| |
| 操作非set对象 → 用 .union() 等方法;双方均为set → 用运算符更简洁 |
| |
| 需作为字典键/嵌套集合 → 用 frozenset |