Python 里除了列表、元组、字典,还有一个经常被新手忽略的内置类型:集合(set)。它最大的特点是元素不重复、无序,天生适合做去重和数学集合运算。今天这篇就带大家把 set 的常用玩法过一遍。
创建集合:花括号与 set() 函数
创建集合有两种方式:直接用花括号包住元素,或者用 set() 构造函数。注意空的花括号 {} 创建的是字典,空集合必须写 set()。
# 用花括号创建
fruits = {"apple", "banana", "orange"}
print(type(fruits)) # <class 'set'>
# 空集合必须用 set()
empty = set()
print(type(empty)) # <class 'set'>
print(type({})) # <class 'dict'>,花括号默认是字典
# 用 set() 把字符串、列表转成集合
chars = set("hello")
print(chars) # {'h', 'e', 'l', 'o'}
集合是无序的,不能用 fruits[0] 按位置取元素,也没有切片操作。
自动去重:一行代码去掉重复元素
往集合里加已存在的元素不会有任何效果,这个特性让 set 成为最顺手的去重工具。
nums = [1, 3, 2, 3, 1, 5, 2]
unique = set(nums)
print(unique) # {1, 2, 3, 5}
# 去重后如果还想要列表,包一层 list() 再排序
sorted_unique = sorted(set(nums))
print(sorted_unique) # [1, 2, 3, 5]
给列表去重再排序,两行就够了。
增删元素:add、remove 与 discard
skills = {"python", "sql"}
skills.add("git") # 添加一个元素
print(skills) # {'python', 'sql', 'git'}
skills.add("git") # 再加一次没变化
print(len(skills)) # 3
skills.remove("sql") # 删除指定元素,不存在会报 KeyError
# skills.remove("java") # KeyError: 'java'
skills.discard("java") # discard 删除不存在的元素不报错
print(skills) # {'python', 'git'}
记住一个小区别:remove() 删不存在的元素会抛异常,discard() 不会。不确定元素在不在时用 discard() 更省心。
交并差:&、|、- 三种运算
set 最有魅力的地方是支持数学里的集合运算,两个集合一组合并能直接算出交集、并集、差集。
frontend = {"html", "css", "js"}
backend = {"python", "js", "sql"}
# 交集 &:两边都有的
print(frontend & backend) # {'js'}
# 并集 |:合在一起去重
print(frontend | backend) # {'html', 'css', 'js', 'python', 'sql'}
# 差集 -:只在左边有的
print(frontend - backend) # {'html', 'css'}
print(backend - frontend) # {'python', 'sql'}
也可以用方法形式:frontend.intersection(backend) 等价于 &,union() 等价于 |,difference() 等价于 -。运算符写法更简洁,方法名更直白。
实际场景比如:有两份用户名单,list_a & list_b 直接得到两边都出现的人;list_a - list_b 得到只在第一份名单里的人。
子集与成员判断
py = {"python"}
langs = {"python", "java", "go"}
print(py <= langs) # True,py 的元素都在 langs 里
print(langs <= py) # False
print("python" in langs) # True
print("rust" in langs) # False
顺带说一个性能点:in 在列表上是逐个比较,越长越慢;在集合上是哈希查找,几乎不耗时。频繁判断存在性的场景,把列表换成集合是零成本优化。
小结
- 集合用花括号创建(空集合是
set()),元素不重复、无序,不支持索引和切片 set(列表)一行去重,配合sorted()得到有序不重复列表- 增删用
add()、remove()(不存在报错)和discard()(不存在不报错) &交集、|并集、-差集,<=判断子集,对应方法名是 intersection、union、difference、issubset- 成员判断
in在集合上远快于列表,频繁查存在性时优先用 set


