Python中的集合(Set)
在Python中,集合(Set) 是一个无序、不重复的序列,它不支持索引。
创建集合
一般在创建集合时,分为创建空集合和非空集合,其创建方式如下:
# 创建空集合
set1 = set()
# 创建同一数据类型元素的集合
set2 = {"a", "b", "c", "d", "e", "f"}
# 创建不同数据类型元素的集合
set3 = {"a", 2, False, ()}
从上面可以看到,我们只需要把集合的所有元素放在 大括号 {}
里面,每个元素之间通过 逗号 ,
间隔起来即可,但需要注意的是,我们创建空集合是不能通过 {}
来创建,因为 {}
表示的是一个空字典。
当然,集合中同样允许存放不同数据类型的元素,但有一点比较特殊,集合中存放的元素必须是不可变对象,而在Python中 list、dict、set 都是可变对象,所以集合中不允许存放 list、dict、set 类型的元素,否则会出现报错。
>>> set1 = {1, [1, 2]}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>>
>>> set1 = {1, {"name": "wintest"}}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>>
>>> set1 = {1, {1, 2}}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
我们在集合中可以存放元组,假如我们在元组中存储有 list、dict、set 类型的对象,然后再把该元组作为一个元素存储到集合中,这样做是否可行呢?
答案是否定的。不管嵌套了多少层,只要集合元素中出现了可变对象,存储到集合时就会出现报错。
集合中元素不可重复
集合中是不允许出现重复元素的,当我们存储多个重复元素到集合中,集合就会自动去重,每个元素只保留一个。
>>> set1 = {1, 2, 1, 3, 4, 1, 5, 2, 3}
>>> set1
{1, 2, 3, 4, 5}
>>>
>>> set2 = {"a", "b", "c", "d", "a", "a", "c"}
>>> set2
{'a', 'd', 'b', 'c'}
集合中元素无序
有时候我们会有一种错觉,认为集合似乎是有序的,比如下面这个例子:
>>> set1 = {2, 6, 5, 4, 1, 3}
>>> set1
{1, 2, 3, 4, 5, 6}
从上面看起来,集合貌似自动进行了排序,但我们在集合中多放几个元素时,就能够明显感受到集合无序的特点,比如下面这个例子:
>>> set1 = {2, 6, 15, 141, 21, 31, 101, 7, 996}
>>> set1
{2, 996, 101, 6, 7, 141, 15, 21, 31}
当我们在使用到集合时,不应该假定其有顺序,即便其可能会有某种顺序,我们也应该把其当作无序进行使用。
添加集合元素
- 通过 add() 添加元素
我们把一个元素添加到集合中,如果集合中已经存在该元素,那么集合不进行任何操作。
>>> set1 = {1, 2, 3, 4}
>>>
>>> set1.add(5)
>>> set1
{1, 2, 3, 4, 5}
>>>
>>> set1.add(3)
>>> set1
{1, 2, 3, 4, 5}
- 通过 update() 添加元素
我们通过 update()
添加元素时,参数必须是可迭代对象,比如可以是 str、list、tuple、set、dict 等类型,该方法不同于 add()
方法,add()
是把参数当作一个整体添加到集合中,而 update()
则是把参数里的所有元素逐一添加到集合中。
>>> set1 = {1, 2, 3, 4}
>>>
>>> set1.update("ab")
>>> set1
{1, 2, 3, 4, 'a', 'b'}
>>>
>>> set1.update([11, 22])
>>> set1
{1, 2, 3, 4, 11, 'a', 22, 'b'}
>>>
>>> set1.update((33, (44, 55)))
>>> set1
{1, 2, 3, 4, 33, 11, 'a', 22, (44, 55), 'b'}
如果添加的元素在集合中已经存在,那么该元素只会出现一次,会忽略掉重复元素。
>>> set1 = {1, 2, 3, 4}
>>>
>>> set1.update([11, 22], (22, 33)) # 添加中有重复元素
>>> set1
{1, 2, 3, 4, 33, 11, 22}
>>>
删除集合元素
- 通过 remove() 删除指定元素,元素不存在则报错
>>> set1 = {1, 2, 3, 4}
>>>
>>> set1.remove(2)
>>> set1
{1, 3, 4}
>>>
>>> set1.remove(2) # 元素不存在,会报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 2
- 通过 discard() 删除指定元素,元素不存在不会报错
>>> set1 = {1, 2, 3, 4}
>>>
>>> set1.discard(2)
>>> set1
{1, 3, 4}
>>>
>>> set1.discard(2) # 元素不存在,并不会报错
>>> set1
{1, 3, 4}
- 通过 pop() 随机删除元素,会返回删除的元素
>>> set1 = {2, 6, 15, 141, 21, 31, 101, 7, 996}
>>>
>>> set1.pop()
2
>>> set1.pop()
996
>>> set1.pop()
101
>>> set1.pop()
6
>>> set1.pop()
7
>>> set1
{141, 15, 21, 31}
如果集合为空时使用 pop()
方法,则会出现报错:
>>> set1 = set()
>>>
>>> set1.pop()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'pop from an empty set'
- 通过 clear() 删除集合所有元素
>>> set1 = {1, 2, 3, 4}
>>>
>>> set1.clear()
>>>
>>> print(set1)
set()
集合运算操作符
- 运算符 & ,取交集,返回2个集合中相同的元素
>>> set1 = {1, 2, 3, 4}
>>> set2 = {1, 5, 6, 4}
>>>
>>> set1 & set2
{1, 4}
- 运算符 | ,取并集,合并2个集合并去除重复元素
>>> set1 = {1, 2, 3, 4}
>>> set2 = {1, 5, 6, 4}
>>>
>>> set1 | set2
{1, 2, 3, 4, 5, 6}
- 运算符 - ,取差集,从集合中去除元素
>>> set1 = {1, 2, 3, 4}
>>> set2 = {1, 5, 6, 4}
>>>
>>> set1 - set2
{2, 3}
>>>
>>> set2 - set1
{5, 6}
- 运算符 ^ ,取对称差集,返回两个集合中不重复的元素集合
>>> set1 = {1, 2, 3, 4}
>>> set2 = {1, 5, 6, 4}
>>>
>>> set1 ^ set2
{2, 3, 5, 6}
- 关键字 in
通过关键字 in
,可检查当前集合中是否包含指定元素,返回结果为布尔值 True 或 False。
>>> set1 = {1, 2, 3, 4}
>>>
>>> print(2 in set1)
True
>>>
>>> print(6 in set1)
False
通过关键字 in
,还可以用于遍历当前集合。
books = {"语文", "数学", "英语", "历史", "物理", "化学"}
for i in books:
print(i, end=" ")
集合常见函数&方法
函数 & 方法 | 描述 |
---|---|
len(set) | 返回集合元素个数 |
max(set) | 返回集合元素最大值 |
min(set) | 返回集合元素最小值 |
set(iterable) | 将可迭代对象转换为集合,若 iterable 为空则创建空集合 |
set.add(obj) | 给集合添加元素 |
set.update(obj) | 给集合添加元素 |
set.remove(obj) | 删除集合中指定元素,元素不存在会报错 |
set.discard(obj) | 删除集合中指定元素,元素不存在不会报错 |
set.pop() | 随机删除元素 |
set.clear() | 清空集合中所有元素 |
set.copy() | 拷贝一个集合,使用的是浅拷贝 |
set1.difference(set2) | 返回多个集合的差集 |
set1.intersection(set2) | 返回集合的交集 |
set1.isdisjoint(set2) | 判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False |
set1.issubset(set2) | 判断指定集合是否为该方法参数集合的子集 |
set1.symmetric_difference(set2) | 返回两个集合中不重复的元素集合 |
set1.union(set2) | 返回两个集合的并集 |