复杂数据类型-集合
# 集合
# 简介
集合与元组和列表相似都用于做容器,在内部可以放一些子元素,但集合有三特殊特点: 子元素不重复
、 子元素必须可哈希
、无序
.
集合:不允许重复元素,而且进行交集以及并集的运算,集合为不可变类型所以不能修改
表示:{} 和dict之间的关系:set中只是存储了key
本质:无序且无重复元素的集合
# 集合的创建/转换
# 创建
使用 {} 创建
setname = {element1,element2,...,elementn} a = {1,'c',1,(1,2,3),'c'} print(a)
1
2
3
4set()函数创建集合
setname = set(iteration) # 其中,iteration 就表示字符串、列表、元组、range 对象等数据。 set1 = set("c.biancheng.net") set2 = set([1,2,3,4,5]) set3 = set((1,2,3,4,5)) print("set1:",set1) print("set2:",set2) print("set3:",set3) set1: {'a', 'g', 'b', 'c', 'n', 'h', '.', 't', 'i', 'e'} set2: {1, 2, 3, 4, 5} set3: {1, 2, 3, 4, 5}
1
2
3
4
5
6
7
8
9
10
11
12
# 转换
其他类型如果想要转换为集合类型,可以通过set进行转换,并且如果数据有重复自动剔除。
提示:int/list/tuple/dict都可以转换为集合。
v1 = [11,22,33,11,3,99,22]
v2 = set(v1)
print(v2) # {11,22,33,3,99}
v1 = "xxx"
v2 = set(v1)
print(v2) # {"x","x","x"}
v1 = (11,22,3,11)
v2 = set(v1)
print(v2) # {11,22,3}
v1 = {"age":12, "status":True,"name":"xxx"}
print( set(v1.keys()) ) # 输出:{'status', 'name', 'age'}
print( set(v1.values()) ) # 输出:{'status', 'name', 'age'}
print( set(v1.items()) ) # 输出:{('age', 12), ('status', True), ('name', 'xxx')}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 增
- add() 添加
- 单个元素,如果添加的元素存在,则添加失败,不报错
- 多个元素,在set中,使用add添加,则只能添加元组,不能添加list和dict
- update() 更新
- 不能直接添加,参数可以是列表,元组,字典等(添加字典的话,只会把key添加进去)
# add(),添加,
set1 = {11, 22, 33, 44, 55}
# 单个元素
set1.add(66)
set1.add(55) # 如果添加的元素存在,则添加失败,不报错
# 多个元素
# s1.add([77,88]) #TypeError: unhashable type: 'list'
s1.add((77, 88))
# s1.add({1:"a"})
# 结论:在set中,使用add添加,则只能添加元组,不能添加list和dict
# update(),更新,update的参数只能是可迭代对象【打碎加入】
set2 = {11, 22, 33, 44, 55}
# set2.update(66) #报错:TypeError: 'int' object is not iterable
set2.update([66]) # []
set2.update((77, 88)) # ()
set2.update({"12": 14, "13": 13}) # 只会把key添加进去
set2.update("hgjhgaa") # 把字符个个的添加进去(不会把重复的添加进去)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 删
- remove() 如果删除的元素不存在,则会发生错误.
- discard() 如果删除的元素不存在,不会发生错误.
- pop() 随机删除集合中的一个元素
- clear() 清空集合
"""
- remove() 如果删除的元素不存在,则会发生错误.
- discard() 如果删除的元素不存在,不会发生错误.
- pop() 随机删除集合中的一个元素
- clear() 清空集合
"""
set2 = {11, 22, 33, 44, 55}
set2.remove(77)
set2.discard(33)
set2.pop()
set2.clear()
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 查
由于集合中的元素是无序的,因此无法向列表那样使用下标访问元素。Python 中,访问集合元素最常用的方法是使用循环结构,将集合中的数据逐一读取出来。
a = {1, 'c', 1, (1, 2, 3)}
for ele in a:
print(ele, end=' ') # 1 c (1, 2, 3)
1
2
3
2
3
# 交集、并集、差集
# 交集
- intersection
- &
s1 = {"刘能", "赵四", "⽪⻓⼭"}
s2 = {"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
s3 = s1 & s2 # 方式一:取两个集合的交集
s4 = s1.intersection(s2) # 方式二:取两个集合的交集
print(s3) # {'⽪⻓⼭'}
print(s4) # {'⽪⻓⼭'}
1
2
3
4
5
6
2
3
4
5
6
# 并集
- union
- |
s1 = {"刘能", "赵四", "⽪⻓⼭"}
s2 = {"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
s3 = s1 | s2 # 方式一:取两个集合的并集
s4 = s1.union(s2) # 方式二:取两个集合的并集
print(s3, s4) # {'刘能', '⽪⻓⼭', '赵四', '冯乡⻓', '刘科⻓'}
1
2
3
4
5
2
3
4
5
# 差集
- difference
s1 = {"刘能", "赵四", "⽪⻓⼭"}
s2 = {"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
s3 = s1 - s2 # 方式一:差集,s1中有且s2中没有的值
s4 = s1.difference(s2) # 方式二:差集,s1中有且s2中没有的值
print(s3,s4) # {'赵四', '刘能'}
s5 = s2 - s1 # 方式一:差集,s2中有且s1中没有的值
s6 = s2.difference(s1) # 方式一:差集,s2中有且s1中没有的值
print(s5,s6) # {'冯乡⻓', '刘科⻓'}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 集合中的方法
dir(set)
['add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
1
2
2
| --- | --- | --- | --- |
# frozenset集合(set集合的不可变版本)
set 集合是可变序列,程序可以改变序列中的元素;frozenset 集合是不可变序列,程序不能改变序列中的元素。set 集合中所有能改变集合本身的方法,比如 remove()、discard()、add() 等,frozenset 都不支持;set 集合中不改变集合本身的方法,fronzenset 都支持。
我们可以在交互式编程环境中输入 dir(frozenset) 来查看 frozenset 集合支持的方法:
>>> dir(frozenset)
['copy', 'difference', 'intersection', 'isdisjoint', 'issubset', 'issuperset', 'symmetric_difference', 'union']
1
2
2
frozenset 集合的这些方法和 set 集合中同名方法的功能是一样的。
两种情况下可以使用 fronzenset:
- 当集合的元素不需要改变时,我们可以使用 fronzenset 替代 set,这样更加安全。
- 有时候程序要求必须是不可变对象,这个时候也要使用 fronzenset 替代 set。比如,字典(dict)的键(key)就要求是不可变对象。
s = {'Python', 'C', 'C++'}
fs = frozenset(['Java', 'Shell'])
s_sub = {'PHP', 'C#'}
#向set集合中添加frozenset
s.add(fs)
print('s =', s) # s = {'Python', frozenset({'Java', 'Shell'}), 'C', 'C++'}
#向为set集合添加子set集合
s.add(s_sub)
print('s =', s)
Traceback (most recent call last):
File "C:\\Users\\mozhiyan\\Desktop\\demo.py", line 11, in <module>
s.add(s_sub)
TypeError: unhashable type: 'set'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
需要注意的是,set 集合本身的元素必须是不可变的, 所以 set 的元素不能是 set,只能是 frozenset。第 6 行代码向 set 中添加 frozenset 是没问题的,因为 frozenset 是不可变的;但是,第 10 行代码中尝试向 set 中添加子 set,这是不允许的,因为 set 是可变的。
编辑 (opens new window)
上次更新: 2023/05/17, 23:08:21