如何在 Python 中创建和使用集合

201 阅读11分钟

简介

在 Python 中,集合是一种存储无序项目的数据结构。集合的项目也是无索引的。像列表一样,集合允许添加和删除元素。然而,有一些独特的特性定义了集合,并将其与其它数据结构区分开来。

  • 一个集合不包含重复的项目
  • 集的元素是不可变的,也就是说,它们不能被改变,但集本身是可变的,也就是说,它可以被改变。
  • 由于集合项没有索引,所以集合不支持任何切分或索引操作。

在本指南中,我们将看看如何在 Python 中创建和使用集合,以及你对它们进行的一些常见操作。

如何在 Python 中创建一个集合

一个集合可以容纳任意数量的项,这些项可以是不同的类型(异质集合),如整数、字符串、图元等等。

注意:一个集合不接受可改变的元素,如列表和字典。

我们可以通过在大括号中传递所有的集合元素来创建一个集合,{} ,并用逗号(,)来分隔这些元素。

num_set = {1, 2, 3, 4, 5, 6}
print(num_set)

这将导致

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

我们刚刚创建了一个数字集。我们还可以创建一个字符串值的集合。

string_set = {"Nicholas", "Michelle", "John", "Mercy"}
print(string_set)

结果是

{'Michelle', 'Nicholas', 'John', 'Mercy'}

**注意:**注意输出中的元素的排序与我们把它们添加到集合中的方式不一样。其原因是,集合项是没有顺序的。如果你再次运行同样的代码,你很可能会得到一个输出,其中的元素以不同的顺序排列。

我们也可以用不同类型的元素创建一个集合。

mixed_set = {2.0, "Nicholas", (1, 2, 3)}
print(mixed_set)

让我们验证一下这是否产生了一个有效的集合。

{2.0, 'Nicholas', (1, 2, 3)}

上面这个集合的所有元素都属于不同的类型。我们也可以从一个列表中创建一个集合。这可以通过调用 Python 内置的set() 方法来实现。

num_set = set([1, 2, 3, 4, 5, 6])
print(num_set)

这就产生了

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

如上所述,集合不包含重复的项目。假设我们的列表有重复的项目。

num_set = set([1, 2, 3, 1, 2])
print(num_set)

集合将只存储列表中的唯一值。

{1, 2, 3}

集合基本上已经删除了重复项,并且只返回每个重复项中的一个。当我们从头开始创建一个集合时也会发生这种情况。

num_set = {1, 2, 3, 1, 2}
print(num_set)

同样,这个集合已经删除了重复的部分,并且只返回了一个重复的项目。

{1, 2, 3}

如果你想创建一个空集合并使用空大括号 ({}),你将创建一个空字典而不是空集合。

x = {}
print(type(x)) # <class 'dict'>

要在Python中创建一个空集,我们只需调用set() 方法而不传递任何值。

x = set()
print(type(x)) # <class 'set'>

如何在 Python 中访问集合项

Python 没有给我们提供一种使用下标符号 (set[index]) 访问单个集合项的方法。然而,我们可以使用一个for 循环来遍历一个集合的所有项。

months = set(["Jan", "Feb", "March", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"])

for m in months:
    print(m)

这将打印months 集合中的每个元素。

March
Feb
Dec
Jan
May
Nov
Oct
Apr
June
Aug
Sep
July

我们还可以使用in 关键字来检查一个集合中是否存在某个元素

months = set(["Jan", "Feb", "March", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"])

print("May" in months)

由于May 存在于months 集合中,这将返回True

True

同样地,搜索一个不存在于集合中的元素,会返回False

months = set(["Jan", "Feb", "March", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"])

print("Nicholas" in months)

这将导致

False

如何向 Python 集合添加项目

Python 允许我们使用add() 方法向一个集合添加新的项目。

months = set(["Jan", "March", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"])

months.add("Feb")
print(months)

项目Feb 将被成功添加到集合中。

{'Oct', 'Dec', 'Feb', 'July', 'May', 'Jan', 'June', 'March', 'Sep', 'Aug', 'Nov', 'Apr'}

如果它是一个数字集,我们就不会像对待字符串那样在引号内传递新元素。

num_set = {1, 2, 3}
num_set.add(4)
print(num_set)

这将把4 添加到num_set

{1, 2, 3, 4}

如何从一个 Python 集合中删除项目

Python 自然允许我们从一个集合中删除一个项,但是我们不能通过索引来删除它,因为集合元素是没有索引的。可以使用discard()remove() 方法来删除这些项目,并引用该特定元素。

**注意:**请记住,如果在集合中找不到该项目,discard() 方法将不会引发错误。然而,如果使用remove() 方法,并且没有找到该项目,将引发错误。

丢弃()

让我们演示一下如何使用**discard()** 方法来删除一个元素。

num_set = {1, 2, 3, 4, 5, 6}
num_set.discard(3)
print(num_set)

元素3 将被从集合中删除

{1, 2, 4, 5, 6}

remove()

同样地,remove() 方法也可以使用如下方法。

num_set = {1, 2, 3, 4, 5, 6}
num_set.remove(3)
print(num_set)

这将产生相同的结果

{1, 2, 4, 5, 6}

删除不存在的元素?

现在,让我们尝试删除一个不存在于集合中的元素。让我们首先使用discard() 方法。

num_set = {1, 2, 3, 4, 5, 6}
num_set.discard(7)
print(num_set)

运行上面的代码不会以任何方式影响集合。

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

现在,让我们看看在同样的情况下使用remove() 方法会发生什么。

num_set = {1, 2, 3, 4, 5, 6}
num_set.remove(7)
print(num_set)

在这种情况下,试图删除一个不存在的元素将引发一个错误。

Traceback (most recent call last):
  File "C:\Users\admin\sets.py", line 2, in <module>
    num_set.remove(7)
KeyError: 7

pop()

通过**pop()** 方法,我们可以删除并返回一个元素。由于元素是无序的,我们不能告诉或预测将被移除的项目。

num_set = {1, 2, 3, 4, 5, 6}
print(num_set.pop())

这将返回从集合中移除的元素。

1

你可以用同样的方法删除一个元素并返回集合中剩余的元素。

num_set = {1, 2, 3, 4, 5, 6}
num_set.pop()
print(num_set)

这将打印出集合中剩余的元素。

{2, 3, 4, 5, 6}

clear()

Python 的clear() 方法帮助我们从一个集合中删除所有的元素。

num_set = {1, 2, 3, 4, 5, 6}
num_set.clear()
print(num_set)

输出是一个空的set() ,里面没有任何元素。

set()

Python 集合的联合

假设我们有两个集合,A 和 B。这两个集合的联合是一个包含两个集合所有元素的集合。这样的操作是通过Python的union() 方法完成的。

例如,假设我们有两个包含月份名称的集合。

months_a = set(["Jan", "Feb", "March", "Apr", "May", "June"])
months_b = set(["July", "Aug", "Sep", "Oct", "Nov", "Dec"])

all_months = months_a.union(months_b)
print(all_months)

运行这段代码后,all_months 集合将包含集合months_amonths_b 的联合。

{'Oct', 'Jan', 'Nov', 'May', 'Aug', 'Feb', 'Sep', 'March', 'Apr', 'Dec', 'June', 'July'}

也可以对两个以上的集合进行联合,它们的所有元素将被合并成一个集合。

x = {1, 2, 3}
y = {4, 5, 6}
z = {7, 8, 9}

output = x.union(y, z)

print(output)

这将导致

{1, 2, 3, 4, 5, 6, 7, 8, 9}

在联合操作过程中,重复的部分会被忽略,只显示其中一个重复的项目。

x = {1, 2, 3}
y = {4, 3, 6}
z = {7, 4, 9}

output = x.union(y, z)

print(output)

这将导致该集合只包含来自起始集合的唯一值。

{1, 2, 3, 4, 6, 7, 9}

| 操作符也可以用来寻找两个或多个集合的联合。

months_a = set(["Jan","Feb", "March", "Apr", "May", "June"])
months_b = set(["July", "Aug", "Sep", "Oct", "Nov", "Dec"])

print(months_a | months_b)

这将产生与使用unoion() 方法相同的结果。

{'Feb', 'Apr', 'Sep', 'Dec', 'Nov', 'June', 'May', 'Oct', 'Jan', 'July', 'March', 'Aug'}

如果你想对两个以上的集合进行联合,可以使用| 操作符将集合名称分开。

x = {1, 2, 3}
y = {4, 3, 6}
z = {7, 4, 9}

print(x | y | z)

这将导致

{1, 2, 3, 4, 6, 7, 9}

Python 集合的交集

假设你有两个集合,A和B,它们的交集是一个在A和B中都有元素的集合。

集合中的相交操作可以使用& 操作符或intersection() 方法来实现。

x = {1, 2, 3}
y = {4, 3, 6}

print(x & y)

唯一的共同元素是3

{3}

同样也可以用intersection() 方法实现。

x = {1, 2, 3}
y = {4, 3, 6}

z = x.intersection(y)
print(z)

这也会导致

{3}

Python 集合之间的区别

假设你有两个集合 A 和 B,*A 和 B 之间的差值 (A - B)是包含所有在 A 中但不在 B 中的元素的集合,因此,(B - A)*是包含 B 中但不在 A 中的所有元素的集合。

要在Python中确定集合的差异,我们可以使用difference() 方法或者- 操作符。

set_a = {1, 2, 3, 4, 5}
set_b = {4, 5, 6, 7, 8}
diff_set = set_a.difference(set_b)
print(diff_set)

上面的代码计算了set_aset_b 之间的差异,因此它们构成了我们的输出。

{1, 2, 3}

减去运算符(-)也可以用来寻找两个集合之间的差异,如下图所示。

set_a = {1, 2, 3, 4, 5}
set_b = {4, 5, 6, 7, 8}
print(set_a - set_b)

这将导致与使用difference() 方法相同的输出。

{1, 2, 3}

集合A和B的对称差是指除了两个集合中共同的元素外,所有元素都在A和B中的集合。它是用Python的symmetric_difference() 方法或^ 操作符确定的。

set_a = {1, 2, 3, 4, 5}
set_b = {4, 5, 6, 7, 8}
symm_diff = set_a.symmetric_difference(set_b)
print(symm_diff)

这将导致

{1, 2, 3, 6, 7, 8}

正如我们之前所说的,对称差也可以用^ 算子找到。

set_a = {1, 2, 3, 4, 5}
set_b = {4, 5, 6, 7, 8}
print(set_a ^ set_b)

这将产生与之前相同的输出。

{1, 2, 3, 6, 7, 8}

Python集合的比较

我们可以根据集合所拥有的元素来进行比较。这样,我们就可以知道一个集合是一个超集还是另一个集合的子集。这种比较的结果将是TrueFalse

为了检查集合A是否是集合B的子集,我们可以使用以下操作。

A <= B

要检查B是否是A的超集,我们可以使用下面的操作。

B >= A

比如说

months_a = set(["Jan", "Feb", "March", "Apr", "May", "June"])
months_b = set(["Jan", "Feb", "March", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"])

subset_check = months_a <= months_b
superset_check = months_b >= months_a

print(subset_check)
print(superset_check)

months_amonths_b 的子集,而 则是months_a 的超集。因此,运行上面的代码将得到。

True
True

子集和超集也可以用issubset()issuperset() 方法来检查,如下所示。

months_a = set(["Jan","Feb", "March", "Apr", "May", "June"])
months_b = set(["Jan","Feb", "March", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"])

subset_check = months_a.issubset(months_b)
superset_check = months_b.issuperset(months_a)

print(subset_check)
print(superset_check)

其结果与上面的例子中的输出相同。

True
True

Python集合方法

在下面的章节中,我们将讨论一些由Python提供的最常用的集合方法,这些方法我们还没有讨论过。

copy()

这个方法返回有关集合的一个副本

string_set = {"Nicholas", "Michelle", "John", "Mercy"}
x = string_set.copy()

print(x)

输出显示:x 是集合string_set 的副本。

{'John', 'Michelle', 'Nicholas', 'Mercy'}

isdisjoint()

这个方法检查有关的集合是否有交集。如果这两个集合没有共同项,该方法返回True ,否则返回False

names_a = {"Nicholas", "Michelle", "John", "Mercy"}
names_b = {"Jeff", "Bosco", "Teddy", "Milly"}

x = names_a.isdisjoint(names_b)
print(x)

这两个集合没有共同项,因此输出为True

True

len()

该方法返回一个集合的长度,也就是该集合中元素的总数。

names_a = {"Nicholas", "Michelle", "John", "Mercy"}

print(len(names_a))

输出显示,该集合的长度为4。

4

Python 冻结集合

Frozenset是一个具有集合特征的类,但是一旦它的元素被分配了,就不能被改变。Tuples 可以被看作是不可变的列表,而冻结集可以被看作是不可变的集合

注意: 集合是可变的、不可哈希的,这意味着我们不能把它们作为字典的键值。冻结的集合是可散列的,我们可以把它们作为字典的键值使用。

为了创建冻结的集合,我们使用frozenset() 方法。让我们创建两个冻结集,XY

X = frozenset([1, 2, 3, 4, 5, 6])
Y = frozenset([4, 5, 6, 7, 8, 9])

print(X)
print(Y)

这将导致

frozenset({1, 2, 3, 4, 5, 6})
frozenset({4, 5, 6, 7, 8, 9})

frozensets支持使用Python集合方法,如copy(),difference(),symmetric_difference(),isdisjoint(),issubset(),intersection(),issuperset(), 和union()

总结

本指南对Python中的集合进行了详细介绍。集的数学定义与Python中集的定义相同。集合只是一个无序的项目的集合。集合本身是可变的,但集合的元素是不可变的。然而,我们可以自由地从一个集合中添加和删除元素。在大多数数据结构中,元素是有索引的。然而,集合元素是没有索引的。这使得我们无法执行针对特定集合元素的操作。