Python集合数据类型详解:定义、创建、访问与删除元素指南
前言

我们之前深入地了解了字典、列表和元组,对于这三个数据类型有了一定的认识。今天,我们来了解另一种数据类型,那就是集合。集合主要是用来保存不重复的元素的,也就是说集合里的元素都是独一无二的。并且集合中的元素只能是不可变的数据类型,像整形、浮点型、字符串以及元组等都可以。而像列表、字典和集合这样的可变数据类型是无法存储在集合中的。
集合 定义概念
集合是无序的,不存在重复元素。其基本用途包含成员测试以及消除重复的条目。集合对象还能够支持数学运算,像并集、交集、差集以及对等差分。
创建集合
1-使用 {} 创建
set_name 中有 (1,2)这个元素 。
print("set_name:", set_name)
# 输出
# set_name 包含了字符串、数字 1、包含数字 1 和 2 的元组以及小数 1.2 。
2-set()函数创建集合
set_name1 = set("帅气的读者")
set_name2 = set([1, 2])
set_name3 = set((1, 2))
打印("set_name1:", set_name1)
打印("set_name2:", set_name2)
打印("set_name3:", set_name3)
# 输出结果
“读”“者”“的”“气”“帅”这几个元素存在于某个设定中。 这个设定被命名为 set_name1 。 其中包含“读”“者”“的”“气”“帅”这些内容。 这些内容构成了 set_name1 的一部分。 它们在 set_name1 中有着特定的关联和意义。
# set_name2: {1, 2}
# set_name3: {1, 2}
访问元素
set_name = set("帅气的读者")
通过枚举(enumerate)集合 set_name 中的元素,获取每个元素的索引 index 和元素 item 。
print(index, item)
# 返回结果
# 0 气
# 1 读
# 2 者
# 3 的
# 4 帅
从上面的返回结果可以看出,集合是无序的
删除元素
remove
set_name = set("帅气的读者")
set_name.remove("的")
for index, item in enumerate(set_name):
print(index, item)
set_name.remove("的")
# 返回结果
# 0 帅
# 1 气
# 2 者
# 3 读
通过 Traceback 可以追踪到程序出错的位置和原因。
在 /Users/linjian/MonitorCenter/MonitorCenter/apps/t6.py 文件中,第 5 行处。
# set_name.remove("的")
# KeyError: '的'
删除集合里的元素时,要注意若被删除的元素原本就不在集合中,那么这种方法就会引发 KeyError 错误。
discard
set_name = set("帅气的读者")
set_name.remove("的")
for index, item in enumerate(set_name):
print(index, item)
set_name.discard("的")
# 返回结果
# 0 读
# 1 帅
# 2 者
# 3 气
此方法的用法与 remove() 方法完全相同,唯一的差异在于,若在删除集合中的元素时失败,此方法不会引发任何错误。
clear:清空 set1 集合中所有元素
set_name = set("帅气的读者")
set_name.clear()
print("set_name:", set_name)
# 返回结果
# set_name: set()
pop:随机删除元素
set_name = set("帅气的读者")
set_name.pop()
print("set_name:", set_name)
# 返回结果
# set_name 包含了“者”“帅”“气”“读”
添加元素
add
set_name = set("帅气的读者")
set_name.add("们")
for index, item in enumerate(set_name):
print(index, item)
# 返回结果
# 0 气
# 1 帅
# 2 们
# 3 的
# 4 者
# 5 读
add()方法所添加的元素,其类型只能是数字、字符串、元组或者布尔类型中的 True 和 False 值。不能添加列表、字典、集合这类可以改变的数据,否则就会报错。
update
set_name = set("帅气的读者")
set_name.update("1")
for index, item in enumerate(set_name):
print(index, item)
# 返回结果
# 0 帅
# 1 者
# 2 读
# 3 1
# 4 的
# 5 气
其他方法
copy:拷贝一个集合(浅拷贝)
set_name = set("帅气的读者")
set_copy = set_name.copy()
print("set_name:", set_copy)
# 返回结果
# 包含“读”“气”“帅”“者”“的”这些字
返回的集合是两个集合的差集,该集合的元素存在于第一个集合里,然而却不存在于第二个集合(也就是方法的参数)中。
有一个集合 set_a ,它包含了“python”“java”“go”这三个元素。 这个集合 set_a 中有的元素是“python”,有的元素是“java”,还有的元素是“go”。 集合 set_a 由“python”“java”“go”这几个元素所组成。
“python”在集合 set_b 中。
通过调用 set 的 difference 方法来实现这一操作。
print(set_a - set_b)
# 返回结果
“java”也在语言之内。
# {'go', 'java'}
difference_update 这个操作是将两个集合中都存在的元素移除掉。 具体来说,就是把在两个集合中都有的那些元素从其中一个集合中去掉。 它的作用就是实现集合之间的差异更新,只保留在一个集合中而不在另一个集合中的元素。
set_a = {"python", "java", "go"}
set_b = {"duck", "fish", "python"}
将 set_a 与 set_b 进行差集更新操作。具体来说,就是从 set_a 中移除那些也在 set_b 中的元素,从而得到一个新的 set_a,这个新的 set_a 只包含那些在原 set_a 中但不在 set_b 中的元素。
print("set_a:", set_a)
# 返回结果
集合 set_a 包含了“go”和“java”这两个元素。“go”在集合 set_a 中,“java”也在集合 set_a 中。
交集是指返回两个或更多集合中都包含的元素。
set_a = {"python", "java", "go"}
set_b = {"duck", "fish", "python"}
打印(集合 a 与集合 b 的交集)
print(set_a & set_b)
# 返回结果
# {'python'}
# {'python'}
intersection_update 能够获取到两个或者更多集合里相互重叠的那些元素,也就是进行交集的计算。
set_a = {"python", "java", "go"}
set_b = {"duck", "fish", "python"}
将 set_a 与 set_b 进行交集更新操作。即从 set_a 中移除不在 set_b 中的元素,只保留 set_a 和 set_b 共有的元素。
print("set_a:", set_a)
# 返回结果
# set_a: {'python'}
判断两个集合是否包含相同的元素,若没有则返回 True,若有则返回 False,这就是 isdisjoint 的作用。
set_a = {"python", "java", "go"}
set_b = {"duck", "fish", "python"}
使用 set_a 和 set_b 进行判断,看它们是否没有交集,即调用 set_a 的 isdisjoint 方法并传入 set_b 作为参数,然后打印出结果
# 返回结果
# False
issubset 用于判断集合的所有元素是否都包含在指定集合中,若都包含则返回 True,若有不包含的元素则返回 False
set_a = {"python", "java", "go"}
set_b = {"duck", "fish", "python"}
print(set_a.issubset(set_b))
# 返回结果
# False
issuperset 用于判断指定集合的所有元素是否都在原始集合之中。若都在,则返回 True;若存在不在的元素,则返回 False。
set_a = {"python", "java", "go"}
set_b = {"duck", "fish", "python"}
判断 set_a 是否是 set_b 的超集。如果是,则返回 True;如果不是,则返回 False。具体来说,就是检查 set_a 中包含的所有元素是否都在 set_b 中,如果是,则 set_a 是 set_b 的超集;如果不是,则 set_a 不是 set_b 的超集。
# 返回结果
# False
返回的是两个集合中不重复的元素所组成的集合,也就是说会把两个集合中都存在的元素给移除掉。
set_a = {"python", "java", "go"}
set_b = {"duck", "fish", "python"}
print(set_a.issuperset(set_b))
print(set_a ^ set_b)
# 返回结果
# 包含 'go'、'java'、'duck'、'fish'
# {'go', 'java', 'duck', 'fish'}
移除当前集合中与另一个指定集合相同的元素;将另一个指定集合中不同的元素插入到当前集合中。
set_a = {"python", "java", "go"}
set_b = {"duck", "fish", "python"}
set_a 与 set_b 进行对称差集更新操作。 即将 set_a 中存在但 set_b 中不存在的元素,以及 set_b 中存在但 set_a 中不存在的元素,添加到 set_a 中。 这样 set_a 就包含了只属于 set_a 或只属于 set_b 的元素,而去除了同时属于 set_a 和 set_b 的元素。 最终 set_a 的元素集合发生了变化,变为了与 set_b 进行对称差集操作后的结果。
print(set_a)
# 返回结果
- 提及“duck”的事宜。
union 可以返回两个集合的并集,这个并集包含了所有集合的元素,并且重复的元素只会出现一次。
set_a = {"python", "java", "go"}
set_b = {"duck", "fish", "python"}
print(set_a.union(set_b))
# 返回结果
fish 是其中一种语言。
集合和字典的区别
python 字典是由哈希表实现的,集合也是由哈希表实现的。它们的区别在于,对于字典来说,哈希表存储了哈希值、键和值这三个元素;而对于集合而言,哈希表内只存储单一的元素。若想了解具体的实现原理,可以查看详解 python 中的字典部分。
集合和字典的性能测试
首先这个测试来源于网上,我觉得还不错就分享过来
# 统计时间需要用到 time 模块中的函数,了解即可
import time
使用列表来查找唯一价格。需要遍历产品列表,对于每个产品,检查其价格是否已经在一个用于存储已出现价格的集合中。如果价格不在集合中,将其添加到集合中;如果价格已经在集合中,说明该价格不是唯一的,跳过该产品。最后,集合中的元素就是所有唯一的价格。
unique_price_list = []
对于每一个空的元素(这里用下划线表示)以及对应的价格,在产品列表中进行遍历。 # 这里的“每一个空的元素”是指在循环中遍历的每个元素,通常是一个索引或键,而“对应的价格”就是与该元素相关联的价格。 # 遍历的范围是整个产品列表,通过循环来逐个处理每个产品及其对应的价格。
如果价格不在唯一价格列表中: # B
unique_price_list 中添加了 price 。
return len(unique_price_list)
创建一个列表 id,这个列表包含从 0 到 99999 的所有整数,即通过 range(0, 100000)生成的一系列数字被添加到 id 列表中。
价格等于在 200000 到 300000 这个范围内的所有 x 组成的列表
将 id 和 price 进行组合,结果以列表形式呈现,这个列表就是 products
# 计算列表版本的时间
使用列表开始的时间为 time.perf_counter() 所记录的时间。
使用列表来查找唯一价格(products)
使用的时间结束,时间记录在 end_using_list 中,这个时间是通过 time.perf_counter()获取的。
打印("使用列表的时间流逝:{}".format(结束使用列表 - 开始使用列表))
# 使用集合完成同样的工作
使用集合来查找唯一价格。对于给定的产品列表,通过集合的特性可以快速找到其中的唯一价格。集合会自动去除重复元素,这样就能准确地找出所有不同的价格。
unique_price_set = set()
for _, price in products:
unique_price_set.add(price)
return len(unique_price_set)
# 计算集合版本的时间
开始使用 set 这个操作的时间是通过 time.perf_counter()函数获取的。
使用集合来查找唯一价格(products)。
end_using_set 等于 time.perf_counter()
打印("使用集合的时间流逝:{}".format(结束使用集合 - 开始使用集合))
返回结果
使用列表时经过的时间为 43.95403001100203
可以发现,仅十万的数据量,两者在速度上的差异就这般之大。大家试想一下,如果数据量再大一些呢?
学习链接
python中的字典和集合
set是如何实现的
list和set的区别