Python Sets详解!

简介: 在 Python 编程中,集合是一种无序、可迭代且可变的数据类型,不包含重复元素,用 `{}` 表示。集合基于哈希表,能高效检查元素是否存在,时间复杂度为 O(1)。集合支持多种操作,如并集、交集和差集。使用 `set()` 方法可进行类型转换,`frozenset()` 创建不可变的冻结集合。集合适用于去重及数学集合运算,但不能通过索引访问元素,且仅支持不可变类型的实例。

嗨,你好啊,我是猿java

在Python编程中,集合是一种无序的、可迭代的、可变的数据类型,并且不包含重复元素。集合用 {} 表示(值用大括号括起来)。

使用集合的主要优势在于它提供了一种高度优化的方法来检查是否包含特定元素。这种方法基于一种称为哈希表的数据结构。由于集合是无序的,我们无法像在列表中那样使用索引来访问元素。

var = {
   "Hello", "worlds", "Sets"}
type(var)

输出:

set
  • 时间复杂度:O(1)
  • 辅助空间:O(1)

使用set方法进行类型转换

Python的 set() 方法用于类型转换。

# 将列表类型转换为集合
myset = set(["a", "b", "c"])
print(myset)

# 向集合中添加元素
myset.add("d")
print(myset)

输出:

{'c', 'b', 'a'}
{'d', 'c', 'b', 'a'}
  • 时间复杂度:O(n)
  • 辅助空间:O(n)

检查唯一性和不可变性

Python 集合不能包含重复值,并且一旦创建后,我们不能改变其值。

# Python 程序演示集合不能包含重复值且不能改变其元素

# 集合不能包含重复值
myset = {
   "Hello", "world", "Hello"}
print(myset)

# 集合的值不能被改变
myset[1] = "Hi"
print(myset)

输出:

{'Hello', 'world'}
TypeError: 'set' object does not support item assignment
  • 第一个代码解释了集合不能包含重复值,每个元素都是唯一的。

  • 第二个代码生成了一个错误,因为我们不能在集合创建后分配或更改其值,只能在集合中添加或删除元素。

Python 集合中的异构元素

Python 集合可以存储异构元素,即集合可以存储字符串、整数、布尔值等数据类型的混合体。

# Python 示例演示集合可以存储异构元素
myset = {
   "Hello", "world", 10, 52.7, True}
print(myset)

输出:

{True, 10, 'Hello', 52.7, 'world'}
  • 时间复杂度:O(n)
  • 辅助空间:O(n)

Python 冻结集合

Python 中的冻结集合是不可变的对象,只支持那些在不影响冻结集合的情况下产生结果的方法和操作。可以使用 frozenset() 方法创建冻结集合。

虽然集合的元素可以随时修改,但冻结集合的元素在创建后保持不变。

如果没有传递参数,它返回一个空的冻结集合。

# Python 程序演示普通集合和冻结集合之间的区别

# 与 {"a", "b","c"} 相同
normal_set = set(["a", "b","c"])

print("普通集合")
print(normal_set)

# 一个冻结集合
frozen_set = frozenset(["e", "f", "g"])

print("\n冻结集合")
print(frozen_set)

# 试图向冻结集合中添加元素,会导致错误
frozen_set.add("h")

输出:

普通集合
{'a', 'c', 'b'}

冻结集合
{'e', 'g', 'f'}

Traceback (most recent call last):
  File "test.py", line 16, in <module>
    frozen_set.add("h")
AttributeError: 'frozenset' object has no attribute 'add'
  • 时间复杂度:O(n)
  • 辅助空间:O(n)

集合的内部工作原理

集合是基于一种称为哈希表的数据结构,如果在同一索引位置存在多个值,则该值将附加到该索引位置,形成一个链表。

在 Python 中,集合使用带有虚拟变量的字典实现,其中键是集合的成员,并对时间复杂度进行了更大的优化。

集合实现:

img

在单个 HashTable 上进行多项操作的集合:

img

集合操作

添加元素

可以通过 set.add() 函数向集合中插入元素,在哈希表中创建一个适当的记录值来存储。与检查项目相同,即平均为 O(1)。但在最坏情况下,它可能变为 O(n)。

# Python 程序演示向集合中添加元素

# 创建一个集合
people = {
   "Jay", "Tom", "Archi"}

print("People:", end = " ")
print(people)

# 这将添加 Daxit 到集合中
people.add("Daxit")

# 使用迭代器向集合中添加元素
for i in range(1, 6):
    people.add(i)

print("\nSet after adding element:", end = " ")
print(people)

输出:

People: {'Tom', 'Archi', 'Jay'}

Set after adding element: {1, 2, 3, 4, 5, 'Tom', 'Archi', 'Jay', 'Daxit'}
  • 时间复杂度:O(n)
  • 辅助空间:O(n)

并集操作

可以使用 union() 函数或 | 操作符合并两个集合。两个哈希表值被访问并遍历,合并操作执行以组合元素,同时删除重复项。这的时间复杂度为 O(len(s1) + len(s2)),其中 s1 和 s2 是需要合并的两个集合。

# Python 程序演示两个集合的并集

people = {
   "Jay", "Tom", "Archil"}
vampires = {
   "Karan", "Arjun"}
dracula = {
   "Deepanshu", "Raju"}

# 使用 union() 函数的并集
population = people.union(vampires)

print("Union using union() function")
print(population)

# 使用 "|" 操作符的并集
population = people | dracula

print("\nUnion using '|' operator")
print(population)

输出:

Union using union() function
{'Karan', 'Tom', 'Jay', 'Arjun', 'Archil'}

Union using '|' operator
{'Deepanshu', 'Tom', 'Jay', 'Raju', 'Archil'}
  • 时间复杂度:O(n)
  • 辅助空间:O(n)

交集操作

可以通过 intersection()& 操作符完成交集操作。选择共同元素。它们类似于迭代哈希列表并组合两个表中的相同值。时间复杂度为 O(min(len(s1), len(s2)),其中 s1 和 s2 是需要合并的两个集合。

# Python 程序演示两个集合的交集

set1 = set()
set2 = set()

for i in range(5):
    set1.add(i)

for i in range(3,9):
    set2.add(i)

# 使用 intersection() 函数的交集
set3 = set1.intersection(set2)

print("Intersection using intersection() function")
print(set3)

# 使用 "&" 操作符的交集
set3 = set1 & set2

print("\nIntersection using '&' operator")
print(set3)

输出:

Intersection using intersection() function
{3, 4}

Intersection using '&' operator
{3, 4}
  • 时间复杂度:O(n)
  • 辅助空间:O(n)

查找集合的差集

查找集合之间的差异。类似于在链表中查找差异。通过 difference()- 操作符完成。查找差异 s1 - s2 的时间复杂度为 O(len(s1))

# Python 程序演示两个集合的差集

set1 = set()
set2 = set()

for i in range(5):
    set1.add(i)

for i in range(3,9):
    set2.add(i)

# 使用 difference() 函数的两个集合的差异
set3 = set1.difference(set2)

print(" Difference of two sets using difference() function")
print(set3)

# 使用 "-" 操作符的两个集合的差异
set3 = set1 - set2

print("\nDifference of two sets using '-' operator")
print(set3)

输出:

Difference of two sets using difference() function
{0, 1, 2}

Difference of two sets using '-' operator
{0, 1, 2}
  • 时间复杂度:O(n)
  • 辅助空间:O(n)

清空集合

set.clear() 方法就地清空整个集合。

# Python 程序演示清空集合

set1 = {
   1,2,3,4,5,6}

print("Initial set")
print(set1)

# 该方法将移除集合的所有元素
set1.clear()

print("\nSet after using clear() function")
print(set1)

输出:

Initial set
{1, 2, 3, 4, 5, 6}

Set after using clear() function
set()
  • 时间复杂度:O(n)
  • 辅助空间:O(n)

Python 集合的两个主要陷阱

  • 集合不以任何特定顺序维护元素。
  • 只有不可变类型的实例可以添加到 Python 集合中。

集合的时间复杂度

操作 平均情况 最坏情况 备注
x in s O(1) O(n)
Union s t O(len(s)+len(t))
Intersection s&t O(min(len(s), len(t)) O(len(s) * len(t)) 如果 t 不是集合,将“min”替换为“max”
Multiple intersection s1&s2&..&sn (n-1)*O(l) 其中 l 是 max(len(s1),..,len(sn))
Difference s-t O(len(s))

集合的操作符

集合和冻结集合支持以下操作符:

操作符 备注
key in s 包含检查
key not in s 非包含检查
s1 == s2 s1 等价于 s2
s1 != s2 s1 不等价于 s2
s1 <= s2 s1 是 s2 的子集
s1 < s2 s1 是 s2 的真子集
s1 >= s2 s1 是 s2 的超集
s1 > s2 s1 是 s2 的真超集
s1 s2 s1 和 s2 的并集
s1 & s2 s1 和 s2 的交集
s1 - s2 s1 中的元素但不在 s2 中
s1 ˆ s2 s1 或 s2 中的元素但不同时存在

关于集合的常见问题

什么是集合?

Python 中的集合是唯一元素的无序集合。可以使用大括号 {}set() 函数定义,并且在存储不同项目和执行数学集合操作(如并集、交集和差集)时非常有用。

# 创建一个集合
my_set = {
   1, 2, 3, 4}
print(my_set)  # 输出: {1, 2, 3, 4}

# 使用 set() 函数
another_set = set([1, 2, 3, 4])
print(another_set)  # 输出: {1, 2, 3, 4}

如何在 Python 中计算集合?

Python 中的集合支持各种操作以计算并集、交集、差集和对称差集。

set1 = {
   1, 2, 3}
set2 = {
   3, 4, 5}

# 并集
print(set1 | set2)  # 输出: {1, 2, 3, 4, 5}

# 交集
print(set1 & set2)  # 输出: {3}

# 差集
print(set1 - set2)  # 输出: {1, 2}

# 对称差集
print(set1 ^ set2)  # 输出: {1, 2, 4, 5}

什么是 Python 中的集合和元组?

  • 集合:一个无序的唯一元素的集合。用大括号 {}set() 定义。元素不能通过索引访问。
  • 元组:一个有序的元素集合。用圆括号 ()tuple() 定义。元素可以通过索引访问。元组是不可变的。

Python 中有集合吗?

是的,Python 中有集合,并且是该语言提供的内置数据类型的一部分。它们常用于成员测试、从序列中删除重复项以及执行集合操作。

my_set = {
   1, 2, 3}
print(2 in my_set)  # 输出: True

如何在 Python 中输入集合?

要在 Python 中输入集合,可以使用 input() 函数获取用户输入,然后将其转换为集合。例如,可以读取用空格分隔的数字字符串并将其转换为整数集合。

# 从用户输入集合
input_str = input("Enter elements separated by space: ")
input_list = input_str.split()  # 将输入字符串拆分为列表
input_set = set(map(int, input_list))  # 将列表转换为整数集合

print(input_set)  # 输出: 输入元素的集合

这个代码片段允许用户输入用空格分隔的一组数字,然后将其转换为整数集合。

总结

Python 中的集合是无序且不重复的元素集合,用大括号 {} 或 set() 定义。集合支持高效的元素检查和基本的集合操作如并集、交集和差集。集合元素可变但不可索引访问。冻结集合 frozenset 是不可变的。集合常用于去重和集合运算。

学习交流

如果你觉得文章有帮助,请帮忙转发给更多的好友,或关注:猿java,持续输出硬核文章。

目录
相关文章
|
JavaScript 前端开发 UED
JS:如何获取浏览器窗口尺寸?
JS:如何获取浏览器窗口尺寸?
660 1
|
5月前
|
人工智能 安全 算法
从“工具过载”到“精准调用”:破解 Agent 工具管理难题
AgentScope Java × Higress:语义驱动工具精选,高效安全降成本。
654 54
|
5月前
|
机器学习/深度学习 人工智能 物联网
Z Image标准版来了!专为微调而生的全能基座,兼顾真实与艺术!
Z-Image标准版正式开源!作为非蒸馏完整模型,它在生成质量、艺术风格多样性(支持动漫/插画等)、微调友好性(LoRA/ControlNet)、CFG精确控制及生成独特性方面全面升级,是开发者定制化图像生成的理想基座。
1425 5
|
11月前
|
SQL 安全 BI
Dataphin数据服务API行级权限管控解决方案 ——构建企业级数据安全的精细化管控体系
Dataphin数据服务推出行级权限管控功能,解决传统权限管理中用户权限分散、管控复杂等问题。支持直连与代理双模式访问,实现API与SQL权限统一管理,满足金融、零售、医疗等行业对数据访问的精细化控制需求。通过动态权限决策引擎和自动化继承体系,确保数据安全且提升应用开发效率。
1051 0
|
Java 编译器 Maven
【颠覆你的认知!】当Quarkus邂逅GraalVM本机镜像,应用启动竟快到飞起——背后的技术秘密等你揭秘!
Quarkus框架因轻量级与高性能而在Java开发社区广受关注。结合GraalVM使用能显著提升应用启动速度与运行效率,这得益于GraalVM的本机镜像支持。本文将介绍如何利用Quarkus和GraalVM构建高效应用,并提供示例代码演示具体步骤。首先需安装GraalVM环境并配置Maven支持构建本机镜像。接着创建一个简单的RESTful服务端点作为示例,通过命令行编译生成本机可执行文件并运行。这种方式能够大幅提升应用性能,但需注意构建时间和部分Java特性兼容性问题。
481 1
|
前端开发 Java UED
SpringMVC全局异常处理+拦截器使用+参数校验
通过使用 SpringMVC 的全局异常处理、拦截器和参数校验,可以有效提升 Web 应用程序的安全性、稳定性和用户体验。这些技术的合理应用,不仅可以保证代码的健壮性,还能提高代码的可维护性,为开发高质量的 Web 应用程序提供了坚实的基础。
512 6
|
存储 关系型数据库 MySQL
从0开始回顾MySQL---系列七
锁 1、为什么要加锁? 1. 当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况,若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。 2. 因此加锁是为了在多用户环境下保证数据库完整性和一致性。 2、MySQL都有哪些锁呢? 锁的分类: ● 按操作分类: ○ 共享锁:也叫读锁。对同一份数据,多个事务读操作可以同时加锁而不互相影响 ,但不能修改数据 ○ 排他锁:也叫写锁。当前的操作没有完成前,会阻断其他操作的读取和写入 ● 按粒度分类: ○ 表级锁:会锁定整个表,开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并
|
安全 Java 应用服务中间件
当遇到非法 URL 参数时,如何保障网页正常打开
访问如`http://example.com?a@b=1`的链接出现400 Bad Request错误,这是因为Tomcat不允许请求目标中含有非法字符。Spring Boot 2可通过配置`server.tomcat.relaxed-query-chars`来允许特殊字符,但这样做可能引入安全风险。因此,建议在Nginx层使用`rewrite_by_lua_block`和`ngx.redirect`进行重定向,将非法字符替换为合法形式,如`http://example.com?ab=1`,同时记录日志以监控。此方案能避免直接修改后端代码,提高安全性。
1034 0
|
C++
gRPC 四模式之 服务器端流RPC模式
gRPC 四模式之 服务器端流RPC模式
527 0
|
负载均衡 算法 Ubuntu
IPVSADM命令详解及负载均衡配置示例
IPVSADM命令详解及负载均衡配置示例
1194 2