# 字面量
{1, 2, 1}{1, 2}
数学中的集合,是由一个或多个确定的元素所构成的整体,具有无序、无重复元素的性质。
Python 中的集合对象,是无序的、无重复元素的可哈希对象的组合。 Python 有 2 种集合数据类型:set(可变)和 frozenset(不可变)。
创建集合对象有 3 种方式: 1. 字面量,用 {} 包围元素,逗号分隔 2. 用 set()、frozenset() 类创建,参数为可迭代对象 3. 集合推导式,类似于列表推导式,将 [] 换成 {}
# 字面量
{1, 2, 1}{1, 2}
{1, 'a', True}{1, 'a'}
# 元素必须是可哈希的
{'a', [1, 2]}--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[3], line 2 1 # 元素必须是可哈希的 ----> 2 {'a', [1, 2]} TypeError: unhashable type: 'list'
# set类, frozenset类
set([1, 2, 1]){1, 2}
set('Hello'){'H', 'e', 'l', 'o'}
set() # 空集合
frozenset()set()
frozenset()
# 集合推导式
{i for i in range(5)}{0, 1, 2, 3, 4}
{2 ** i for i in range(5)}{1, 2, 4, 8, 16}
{x ** 2 for x in [1, 1, 2]}{1, 4}
中学数学的集合运算(交、并、补、差)以及集合关系判断(子集、超集),可以通过运算符或方法实现:
| 类型 | 运算符 | 方法 | 含义 |
|---|---|---|---|
| 集合运算 | | |
union |
并集 |
& |
intersection |
交集 | |
- |
difference |
差集 | |
^ |
symmetric_difference |
对称差 | |
| 集合关系 | == / != |
— | 是否相等/不等 |
< / <= |
issubset |
是否是(真)子集 | |
> / >= |
issuperset |
是否是(真)超集 | |
| — | isdisjoint |
是否不相交 |


此外,集合还支持 len()、max()/min()(要求元素可比较大小)、sum()(要求元素是数值类型)、in/not in。
s1 = {1, 3, 5, 7, 9}
s2 = {1, 2, 3}
print(s1 | s2) # 并集
print(s1 & s2) # 交集
print(s1 - s2) # 差集
print(s1 ^ s2) # 对称差{1, 2, 3, 5, 7, 9}
{1, 3}
{9, 5, 7}
{2, 5, 7, 9}
s1 = {1, 3, 5}
s2 = {1, 2, 3, 4, 5}
print(s1 < s2) # 真子集
print(s1 <= s2) # 子集
print(s2 > s1) # 真超集
print(s1.isdisjoint({2, 4})) # 不相交?True
True
True
True
set 是可变集合,支持以下修改操作:
s = {1, 2, 3}
s.add(4) # 添加元素
print(s)
s.remove(2) # 移除元素(不存在则报错)
print(s)
s.discard(10) # 移除元素(不存在不报错)
print(s)
print(s.pop()) # 随机取出一个元素
print(s){1, 2, 3, 4}
{1, 3, 4}
{1, 3, 4}
1
{3, 4}
# 列表去重(但会丢失顺序)
nums = [1, 2, 2, 3, 3, 3, 4]
unique = list(set(nums))
print(unique)[1, 2, 3, 4]
# 找出两个列表中的共同元素
a = [1, 2, 3, 4, 5]
b = [4, 5, 6, 7, 8]
common = set(a) & set(b)
print(common){4, 5}
集合的 Jaccard 系数用于衡量两个集合的相似度,定义为 J(A, B) = \dfrac{|A \cap B|}{|A \cup B|}。写一个函数 jaccard(s1, s2) 计算两个字符串的 Jaccard 系数(将字符串视为字符的集合)。
提示:可以利用集合的 & 运算符求交集、| 运算符求并集。
def jaccard(s1, s2):
# 将字符串转为集合,计算 Jaccard 系数
pass
# 测试
print(jaccard('apple', 'apples'))
print(jaccard('hello', 'world'))None
None