Python Sets详解!

嗨,你好啊,我是猿java

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

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

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

输出:

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

使用set方法进行类型转换

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

1
2
3
4
5
6
7
# 将列表类型转换为集合
myset = set(["a", "b", "c"])
print(myset)

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

输出:

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

检查唯一性和不可变性

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

1
2
3
4
5
6
7
8
9
# Python 程序演示集合不能包含重复值且不能改变其元素

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

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

输出:

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

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

Python 集合中的异构元素

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

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

输出:

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

Python 冻结集合

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 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")

输出:

1
2
3
4
5
6
7
8
9
10
普通集合
{'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)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 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)

输出:

1
2
3
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 是需要合并的两个集合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 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)

输出:

1
2
3
4
5
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 是需要合并的两个集合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 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)

输出:

1
2
3
4
5
Intersection using intersection() function
{3, 4}

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

查找集合的差集

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 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)

输出:

1
2
3
4
5
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() 方法就地清空整个集合。

1
2
3
4
5
6
7
8
9
10
11
12
# Python 程序演示清空集合

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

print("Initial set")
print(set1)

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

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

输出:

1
2
3
4
5
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 中的元素但不同时存在

关于集合的常见问题

什么是集合?

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

1
2
3
4
5
6
7
# 创建一个集合
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 中的集合支持各种操作以计算并集、交集、差集和对称差集。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 中有集合,并且是该语言提供的内置数据类型的一部分。它们常用于成员测试、从序列中删除重复项以及执行集合操作。

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

如何在 Python 中输入集合?

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

1
2
3
4
5
6
# 从用户输入集合
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,持续输出硬核文章。

drawing