当前位置:首页>python>Python集合(set)超全详解|零基础看懂

Python集合(set)超全详解|零基础看懂

  • 2026-09-17 18:57:11
Python集合(set)超全详解|零基础看懂

一、什么是集合 set?

1. 核心定义

set 是 Python 内置无序、不重复的可变序列容器,属于无序可变数据类型,用大括号 {} 标识。 和列表 list、元组 tuple、字典 dict 并列四大基础容器。

2. 三大核心特性(考试/开发高频考点)

  1. 元素唯一,自动去重集合内不允许存在重复数据,写入重复元素会自动丢弃,这是集合最常用的功能。
  2. 无序存储,无下标索引集合不记录元素存入顺序,每次打印顺序随机,不能用 [下标] 取值、切片。
  3. 元素必须是不可变类型(可哈希 hashable)集合内部依靠哈希值存储数据,能计算哈希的数据才能放进集合: ✅ 允许:int、float、str、tuple、布尔值 ❌ 禁止:list、dict、set(可变类型无法哈希,放进去直接报错)

3. 集合适用场景

  • 快速对列表、字符串去重(最简单高效的去重方案)
  • 数据交集、并集、差集、对称差集对比(筛选共同/独有数据)
  • 判断元素是否存在(in 查询效率远高于列表)

二、集合的两种创建方式

方式1:直接大括号 {} 创建

语法:变量 = {元素1, 元素2, 元素3...}

# 数字集合
num_set = {1, 2, 3, 3, 2, 1}
print(num_set)  # 输出 {1,2,3} 自动去重

# 字符串集合
str_set = {"苹果", "香蕉", "橙子", "苹果"}
print(str_set)  # {'香蕉', '橙子', '苹果'} 无序+去重

# 混合类型集合(仅支持不可变类型)
mix_set = {100, "python", (1, 2), True}
print(mix_set)

⚠️ 重点坑:空集合不能用 {}{} 代表空字典,创建空集合必须使用 set()

# 错误:创建的是空字典
empty_wrong = {}
print(type(empty_wrong))  # <class 'dict'>

# 正确:创建空集合
empty_set = set()
print(type(empty_set))  # <class 'set'>

方式2:内置函数 set() 强制转换创建

可以把可迭代对象(列表、元组、字符串、range)转为集合,自动去重。 语法:变量 = set(可迭代对象)

# 1. 列表转集合(经典去重)
lst = [1,1,2,2,3]
s1 = set(lst)
print(s1)  # {1,2,3}

# 2. 元组转集合
tup = (5,5,6)
s2 = set(tup)

# 3. 字符串转集合(拆分单个字符,自动去重)
text = "abacada"
s3 = set(text)
print(s3)  # {'a','b','c','d'}

# 4. range区间转集合
s4 = set(range(1,6))
print(s4)  # {1,2,3,4,5}

小案例:一行代码列表去重(工作常用)

old_list = [2, 4, 2, 6, 4, 8]
# 列表→集合去重→转回列表
new_list = list(set(old_list))
print(new_list)

补充缺点:集合无序,转换后原有顺序会丢失;Python3.7+如需保留顺序可改用字典去重,文末会补充替代方案。


三、集合常用增删改查操作

set 是可变类型,支持新增、删除元素,但不支持修改单个指定元素(无下标)。

1. 添加元素

① add():添加单个元素

不存在则新增,存在则无任何变化,不报错

s = {1,2,3}
s.add(4)
s.add(2)  # 已有2,不生效
print(s)  # {1,2,3,4}

② update():批量添加多个元素,接收可迭代对象

支持列表、字符串、元组,会拆分内部元素逐一加入

s = {1,2}
# 添加列表
s.update([3,4])
# 添加字符串(拆分每个字符)
s.update("ab")
print(s)  # {1,2,3,4,'a','b'}

2. 删除元素 4种方法对比

方法
作用
元素不存在时
remove(x)
删除指定元素
报错 KeyError
discard(x)
删除指定元素
无任何提示(推荐)
pop()
随机删除一个元素并返回
空集合报错
clear()
清空集合所有元素
无报错,返回空集合

代码示例:

s = {10,20,30,40}

# 1. discard 推荐使用,容错高
s.discard(20)
s.discard(999)  # 不存在不报错

# 2. remove 不存在会报错
s.remove(30)
# s.remove(999)  # 代码直接崩溃

# 3. pop 随机删一个
del_item = s.pop()
print("被删除的元素:", del_item)

# 4. clear 清空全部
s.clear()
print(s)  # set()

3. 查询操作

集合不能索引取值,仅两种查询方式:

① 判断元素是否存在 in / not in

查询效率远超列表,海量数据筛选优先用集合

s = {"张三", "李四", "王五"}
print("张三"in s)    # True
print("赵六"notin s) # True

② 遍历循环 for

name_set = {"张三", "李四"}
for name in name_set:
    print(name)

4. 修改集合

集合没有直接修改单个元素的方法,如需修改思路:

  1. 删除旧元素
  2. 添加新元素
s = {1,2,3}
# 把2改成22
s.remove(2)
s.add(22)
print(s) # {1,3,22}

5. 其他基础内置函数

s = {1,3,5,7}
len(s)    # 获取元素个数 4
max(s)    # 最大值 7
min(s)    # 最小值 1

四、集合数学运算(开发高频:数据对比)

两个集合之间可做交集、并集、差集、对称差集,支持运算符和方法两种写法。 定义两组测试数据:

set_a = {1, 2, 3, 4, 5}
set_b = {4, 5, 6, 7, 8}

1. 并集 | :两个集合全部元素,去重

包含A所有元素 + B所有元素

# 运算符写法
res1 = set_a | set_b
# 方法写法 union()
res2 = set_a.union(set_b)
print(res1) # {1,2,3,4,5,6,7,8}

2. 交集 & :两个集合共同存在的元素

只保留两边都有的数据(筛选共同好友、重复数据)

res1 = set_a & set_b
res2 = set_a.intersection(set_b)
print(res1) # {4,5}

3. 差集 - :属于A但不属于B的元素

res1 = set_a - set_b
res2 = set_a.difference(set_b)
print(res1) # {1,2,3}

4. 对称差集 ^ :只在其中一边出现的元素

排除两者共有,只保留独有数据

res1 = set_a ^ set_b
res2 = set_a.symmetric_difference(set_b)
print(res1) # {1,2,3,6,7,8}

5. 子集/超集判断(返回布尔值)

s1 = {1,2}
s2 = {1,2,3}

# 子集:s1所有元素都在s2中 s1 <= s2
print(s1.issubset(s2)) # True

# 超集:s2包含s1全部元素 s2 >= s1
print(s2.issuperset(s1)) # True

五、不可变集合 frozenset

普通 set 可变,不能作为字典的键、放入其他集合;如果需要只读、不可修改的集合,使用 frozenset。

特性

  1. 创建后无法增删元素,无 add、remove、update 方法
  2. 可哈希,能作为字典key、存入普通set
# 创建不可变集合
fs = frozenset([1,2,3])
print(type(fs)) # <class 'frozenset'>

# fs.add(4) 报错,不支持修改操作

# 可做字典键
dic = {fs: "测试"}
print(dic)

适用场景:需要集合作为字典键、保证数据全程不可修改。


六、实操完整案例

案例1:列表一键去重(基础)

# 原始重复数据
user_ids = [101, 102, 101, 103, 102, 104]
# 集合去重
unique_ids = list(set(user_ids))
print("去重后:", unique_ids)

案例2:筛选两个列表共同用户(交集实战)

# 班级1学生
class1 = ["小明", "小红", "小刚", "小丽"]
# 班级2学生
class2 = ["小红", "小亮", "小丽", "小宇"]

# 转集合求交集
s1 = set(class1)
s2 = set(class2)
same_student = s1 & s2
print("两个班都有的学生:", same_student)

案例3:找出只在班级1,不在班级2的学生(差集)

only_class1 = s1 - s2
print("仅一班学生:", only_class1)

案例4:保留顺序的列表去重(解决set无序缺陷)

Python3.7+字典key有序,替代集合去重,不打乱原有顺序

old = [2, 2, 1, 3, 1]
new = list(dict.fromkeys(old))
print(new) # [2,1,3] 保留原始顺序

七、集合常见易错坑总结

  1. ❌ 空集合不能写 {},{} 是空字典,必须 set()
  2. ❌ 集合无序,不能使用下标 s[0]、切片操作
  3. ❌ 可变类型 list/dict/set 不能放入集合,会报哈希错误
  4. ❌ remove() 删除不存在元素直接崩溃,优先用 discard()
  5. ❌ 列表转集合去重会丢失原有排序,需要有序去重用字典方案
  6. ❌ 普通set不能作为字典的键,要用 frozenset

八、文末总结

集合 set 是 Python 专门为去重、数据比对设计的数据容器,核心优势是元素自动唯一、成员查询速度极快。日常开发中,列表去重、用户数据对比、筛选重复数据都离不开集合。 分清可变 set 和不可变 frozenset,掌握增删方法与四大集合运算,就能覆盖90%以上的业务场景。 同时要避开无序、哈希类型、空集合创建等高频踩坑点,写出简洁高效的Python代码。

最新文章

随机文章