在 python
中,集合是一个无序的,不重复的数据组合,他的主要工作如下:
1、去重,把一个列表变成集合,就自动去重了
2、关系测试,测试两组数据之间的交集、差集、并集等关系
我来举个例子,前两个月出了 iPhoneXS
,去年出了 iPhoneX
,我现在想知道有多少人不仅去年买了 iPhoneX
今年也买了iPhoneXS
,如下两个数组:
iPhoneX = ['张三','李四','王五','赵六']
iPhoneXS = ['刘一','李四','周八','郑十','张三']
我要得出两部手机都买了的人按照之前学过的来做的话,肯定要两部循环,如:
iPhoneX = ['张三','李四','王五','赵六']
iPhoneXS = ['刘一','李四','周八','郑十','张三']
user = list()
for i in iPhoneX:
if i in iPhoneXS:
user.append(i)
print(user)
输出结果为:['张三', '李四']
如果再更改需求,我需要把买过 iPhoneXS
和 iPhoneX
的人合并在一起,并且去除重复购买的人该怎么做呢,如果按照之前学过的几种基本类型来做的话,我首先要再建立一个 数组,并且把买过 iPhoneX
和 iPhoneXS
的人拼接到一个数组中,然后根据已经得到的 user 循环判断,删除和 user
重复的所有数据,然后再把 user
拼接进去就得到了我想要的数据,思路是这样没错,可是 python
还是嫌它太麻烦了,所以就有了一个 集合类型,来看看集合是怎么操作的:
首先语法和 字典 一样都是 {}
号包裹着的,和 字典
不同的是,在 字典
里面是有 key
和 value
值的,而 集合
是没有 key
的,他直接就是 value
值,如:
a = {1,2,3,4,5,6}
注意,如果 集合
内部没有一个值,他默认是 字典
类型,我来做个测试判断,如:
a = {1,2,3,4,5,6}
type(a)
>> <class 'set'> #集合类型
a = {}
print(type(a))
>> <class 'dict'> #字典类型
集合中的内部元素有三个特性:
1、确定性(元素必须可 hash)
2、互异性(去重复)
3、无序性(集合中的元素没有先后之分)
先看看它去重复的功能,还是用最上方的例子来解释
iPhoneX = ['张三','李四','王五','赵六']
iPhoneXS = ['刘一','李四','周八','郑十','张三']
arr = iPhoneX+iPhoneXS
print(set(arr))
>> {'赵六', '王五', '郑十', '李四', '周八', '刘一', '张三'}
可以看到我直接用他的类型 set()
方法,就直接将一个数组去重并且转成 集合类型
,同样的我用数组的方法 list
再把它转成数组就直接 ok
了:
iPhoneX = ['张三','李四','王五','赵六']
iPhoneXS = ['刘一','李四','周八','郑十','张三']
arr = iPhoneX+iPhoneXS
print(list(set(arr)))
>> ['刘一', '赵六', '李四', '周八', '王五', '郑十', '张三']
这就是 集合
的强大之处,一个简单的操作完成了很多复杂的逻辑化处理,关于 集合
的基本操作方法确实还有很多,下面我来一一演示
add(需要增加的内容)
: 增加 (注意:这里只能添加一个值,如果添加多个值会报错
)
update()
: 增加(增加多个值,如果重复了会被自动剔除,注意:这里的添加必须写如一个数组
)
pop()
: 随机删除(注意:这里的可能在数据不多的情况下可能是删除第一个或者最后一个,但是只要数据量足够大,它一定是随机删除的
)
remove(参数)
: 指定删除(通过传递参数指定删除某一个元素,注意:如果指定的元素不存在,则会报错
)
discard(参数)
: 指定删除(通过传递参数指定删除某一个元素,和 remove()
方法相反的是如果不存在,并不会报错)
clear()
: 清空整个集合
add():
a = {1,2,3,4,5}
a.add(6)
print(a)
>> {1,2,3,4,5,6}
a.add(2)
print(a)
>> {1,2,3,4,5,6} #已经存在的值是增加不进去的,集合的特性就是不重复
update():
a = {1,2,3,4,5}
a.update([4,5,6,7,8,9,0]) # 在 update 方法里面添加集合必须以数组的方式加进去
print(a)
>> {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
pop():
a = {1,2,3,4,5,6,7,8,9,0}
a.pop()
print(a)
>> set({1, 2, 3, 4, 5, 6, 7, 8, 9})
remove():
a = {1,2,3,4,5,6,7,8,9,0}
a.remove(5)
print(a)
>> set({1, 2, 3, 4, 6, 7, 8, 9, 0}) #删除完成后变量 a 已经没有 5 这个变量值了
a.remove(5) #删除没有的元素在控制台会报以下错误
>> Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 5
discard():
a = {1,2,3,4,5,6,7,8,9,0}
a.discard(5)
print(a)
>> set({1, 2, 3, 4, 6, 7, 8, 9, 0}) #删除完成后变量 a 已经没有 5 这个变量值了
a.discard(5) #控制台并不会报错
>>
clear():
a = {1,2,3,4,5,6,7,8,9,0}
a.clear()
print(a)
>> set() # 空集合
好了 基本
的 集合类方法
已经讲解完毕了,其实上面说了这么多都是关于集合去重复的一些常规的 增删改查
,其实集合还有一个关键的重点,那就是 关系测试
。
关系测试
关系测试分为交集
、差集
、并集
这么几种,可能很多朋友对这几个关键词比较迷惑,其实啊,在我看到 交集
、差集
、并集
这三种名称的时候同样的迷惑,先来了解以下这三种分别代表什么意思,在来说说 集合
能怎么处理这几种关系测试。
交集:
如上方例子,再看下方示意图,就是又买了 iPhoneX
也买了 iPhoneXS
的人,这样类型的数据就是交集。
intersection()
: 查找交集数据或这直接简写成 &
intersection()
iPhoneX = ['张三','李四','王五','赵六']
iPhoneXS = ['刘一','李四','周八','郑十','张三']
a = set(iPhoneX).intersection(set(iPhoneXS))
print(a)
>> {'张三', '李四'}
intersection() 简写 &
iPhoneX = {'张三','李四','王五','赵六'}
iPhoneXS = {'刘一','李四','周八','郑十','张三'}
print(iPhoneX & iPhoneXS)
>> {'张三', '李四'}
差集:
我们已经知道了怎么获取交集,什么又是差集呢,差集就是非交集的都算是差集,看到下图,我现在能获取到 iPhoneX
和 iPhoneXS
都买了的人但是我现在要获取只买了 iPhoneX
和 iPhoneXS
的人,那么这种只买了 iPhoneX
和 iPhoneXS
的人就是差集,如下图:
difference()
: 查找差集数据或这直接简写成 -
difference()
iPhoneX = {'张三','李四','王五','赵六'}
iPhoneXS = {'刘一','李四','周八','郑十','张三'}
#查找只购买了 iPhoneX 的人
a = iPhoneX.difference(iPhoneXS)
print(a)
>> {'赵六', '王五'}
difference() 简写 –
iPhoneX = {'张三','李四','王五','赵六'}
iPhoneXS = {'刘一','李四','周八','郑十','张三'}
#查找只购买了 iPhoneX 的人
a = iPhoneX - iPhoneXS
print(a)
>> {'王五', '赵六'}
并集:
并集其实很好理解,就是两个集合全部相加在一起,然后去除重复的内容就叫并集
union()
: 将两个集合转换成一个集合,并且去除重复的内容可以简写成 |
union()
iPhoneX = {'张三','李四','王五','赵六'}
iPhoneXS = {'刘一','李四','周八','郑十','张三'}
a = iPhoneX.union(iPhoneXS)
print(a)
>> {'张三', '赵六', '郑十', '周八', '刘一', '王五', '李四'}
union() 简写成 |
iPhoneX = {'张三','李四','王五','赵六'}
iPhoneXS = {'刘一','李四','周八','郑十','张三'}
a = iPhoneX | iPhoneXS
print(a)
>> {'张三', '赵六', '郑十', '周八', '刘一', '王五', '李四'}
好了集合类型一共就是上方三种,可以算基本上完了,但是差集还有一个小知识点,那就是 对称差集
对称差集
对称差集又是什么呢?用上方的例子来说就是只取买了 iPhoneX
和 iPhoneXS
如果都买了就会被过滤掉,如果用上方的讲过的几个知识点来做的话,可能需要这样做:
iPhoneX = {'张三','李四','王五','赵六'}
iPhoneXS = {'刘一','李四','周八','郑十','张三'}
a = iPhoneX - iPhoneXS #iPhoneX 的差集
b = list(iPhoneXS - iPhoneX) #iPhoneXS 的差集并且转成数组
a.update(b) 将数组 b 添加进集合 a 里
print(a)
>> {'王五', '郑十', '周八', '刘一', '赵六'}
可以看到根据上方所学可以这样就求出了只买了 iPhoneX
和 iPhoneXS
的人,直接过滤了两者都买了的人。
其实上方代码已经很简洁了,可是 python
还是嫌弃他比较繁琐,所以又提供了一个内置的方法:symmetric_difference()
symmetric_difference()
: 求出对称差集,可以简写成 ^
symmetric_difference()
iPhoneX = {'张三','李四','王五','赵六'}
iPhoneXS = {'刘一','李四','周八','郑十','张三'}
a = iPhoneX.symmetric_difference(iPhoneXS)
print(a)
>> {'周八', '郑十', '王五', '赵六', '刘一'}
symmetric_difference()
简写方案 ^
iPhoneX = {'张三','李四','王五','赵六'}
iPhoneXS = {'刘一','李四','周八','郑十','张三'}
a = iPhoneX ^ iPhoneXS
print(a)
>> {'郑十', '赵六', '王五', '刘一', '周八'}
可以看到,对称差集
就求出来了,接下来继续往下看看集合的对应关系。
集合的对应关系
什么是集合的对应关系呢?举个最简单的例子:
一个城市的多级联动,省级以下是市级的单位,市级以上是省级,那么在 python
里面省级就是市级的 超集
,市级就是省级的 子集
这个时候我有一份省级的人物名单和好几份市级的人名单,如:
Province = {'a','b','c','d','e','f','g'} #省级
city1 = {'w','e'} #城市一
city2 = {'f','e'} #城市二
city3 = {'j','k'} #城市三
city4 = {'z','k'} #城市四
city5 = {'a','h'} #城市五
我需要判断这些市级有那些是属于这个省级的子集那么该怎么做呢?python
也为我们提供了可以判断层级关系的内置方法:
issubset()
: 判断一个集合内的所有元素是否被包含在另一个集合内 (简写方式为 <=
)
issuperset()
: 判断一个集合内的元素是否包含了另一个集合的所有元素(和上方相反简写方式为 >=
)
根据这个城市的小例子,上方数据不是很多,一眼就可以看到只有城市二的所有元素,是省级单位都包括了的,所以其他的城市我就不测试了,直接用城市二来测试,如:
Province = {'a','b','c','d','e','f','g'} #省级单位
city2 = {'f','e'} #城市二
a = Province.issuperset(city2) #判断省份里面是否包含了 市级
b = city2.issubset(Province) #判断市级是否被包含在省级内
print(a)
print(b)
>> True
>> True
简写方式:
Province = {'a','b','c','d','e','f','g'} #省级单位
city2 = {'f','e'} #城市二
a = Province >= city2 #判断省份里面是否包含了 市级
b = city2 <= Province #判断市级是否被包含在省级内
print(a)
print(b)
>> True
>> True
python
还为我们提供了一个方法用来判断两个集合是不是不相交的。
isdisjoint()
: 用来判断两个集合是不是不相交的,如果相交,返回 False, 如果不相交,返回 True
isdisjoint()
city2 = {'f','e'}
a = city2.isdisjoint(city2) #city2和它自身是相交的,所以返回的是 false ,只有不相交才会返回 true
print(a)
>> False
好了,还有最后两个内置方法:
difference_update()
: 差集赋值
intersection_update()
: 交集赋值
difference_update()
a = {1,2,3,4,5,6,7,8,9,0}
b = {1,2,3,4,5,6,7}
a.difference_update(b) #将取到的差集赋值给 a 改变了 a 原有的值
print(a)
>> {0, 8, 9}
intersection_update()
a = {1,2,3,4,5,6,7,8,9,0}
b = {1,2,3,4,5,6,7}
a.intersection_update(b) #将取到的交集赋值给 a 改变了 a 原有的值
print(a)
好了关于集合类型基本上全部完了,加上前面的几个章节基本上关于 python
的所有基本类型就彻底学完了要学习关于 python
新的知识了。