我们将在这一章中讲解如何使用集合,集合是Python 的内置类型之一。有两种类型,set类型和frozenset类型,set类型是可变的,所以你可以在以后添加或删除元素。frozenset 类型是不可变的,以后不能更改。集合的元素没有顺序,并且不能有重复的元素。
目录
13-1 创建一个集合
13-2 从字符串、元组、范围等创建集合
13-3 获取集合的长度(元素个数)
13-4 向集合中添加元素和从集合中删除元素
13-5 集合之间的关系
13-6 对集合执行操作(并集、交集、差集、对称差集)
13-7 检查集合是否包含与指定值相同的元素
我们将解说如何创建一个新集。一个集合包含多个元素。没有构造函数只能创建集合类型。frozenset 类型是使用构造函数创建的。
通过指定值创建集合(集合类型)
集合类型( set type )是通过在 { } 之间用逗号(,)分隔多个元素来定义的。格式如下。
{元素1, 元素2, ...}
请注意,使用 { } 与字典型相同,但是不同之处在于字典具有键:值格式的元素。
只有可以散列的对象(即不可变对象,如数字、字符串和元组)才能指定为集合中的值。
{10, 30, 50}
{"Orange", "Lemon", "Peach"}
可以为同一集合中的每个元素指定不同数据类型的对象。
{1, "Hello", (3, "CD")}
你可以用空元素创建一个集合,但如果你这样写,元素将是一个空字典。
{} <-- 包含空元素的字典
如果要创建一个空的元素集,请使用 set 类型构造函数来创建它,如下所示:
set()
生成的词典可以分配给数值或字符串等变量来使用。
myset = {"Orange", "Lemon", "Peach"}
集合类型对象的注意事项
集合类型的对象包含多个元素,但集合类型中的元素没有顺序。因此,当包含多个元素时,我不知道它们的排列顺序是什么。
此外,集合类型的对象不能存储多个具有相同值的元素。添加具有相同值的元素不会出错,但是具有相同值的元素被组合在一起。
以下示例创建一个集合,其中包含五个字符串“H”、“a”、“p”、“p”、“y”作为集合的元素。
myset = {"H", "a", "p", "p", "y"}
print(myset)
>> {'H', 'y', 'a', 'p'}
使用print函数打印创建的集合时,可以看到元素的输出形式与创建集合时指定的字符串顺序不同。此外,指定了两个“p”,但它们合并为一个,元素数为 4。
指定分配给变量的值作为元素
通过指定值创建集时,可以不直接输入值,而是指定分配该值的变量来创建集合。
x = 10
y = 20
myset = {x, y}
print(myset)
>> {10, 20}
如果为元素指定了变量名,它将被视为直接写入创建集合时分配给变量的值,而不是在元素中设置对变量的引用。所以之前的集合与创建的集合完全相同:
myset = {10, 20}
print(myset)
>> {10, 20}
创建字典后为变量分配不同的值不会更改字典的元素。
x = 10
y = 20
myset = {x, y}
print(myset)
>> {10, 20}
y = 40
print(myset)
>> {10, 20}
可以通过将字符串、元组或范围指定为构造函数的参数来创建集合类型 set 和 frozenset 类型。这里我们解释如何从字符串、元组、范围等创建集合。
从可迭代对象创建一个集合
一些集合构造函数通过将可迭代对象指定为参数来创建集合对象。
class set([iterable])
class frozenset([iterable])
可迭代对象是列表、元组、字符串、字典等。
从字符串创建一个集合
首先,让我们通过指定一个字符串作为参数来创建一个集合类型对象。
myset = set("Hello Python")
print(myset)
>> {'t', 'h', ' ', 'l', 'y', 'o', 'P', 'n', 'e', 'H'}
将创建一个新集合,其中指定为参数的字符串中的每个字符都有一个元素。需要注意的是,集合的元素没有顺序,因此无法知道元素的排列顺序。此外,由于一个集合只能有一个具有相同值的元素,因此具有相同值的元素被组合在一起。
让我们以相同的方式创建一个以字符串作为参数的 frozenset 类型对象。
myfrozenset = frozenset("Hello Python")
print(myfrozenset)
>> frozenset({'t', 'h', ' ', 'l', 'y', 'o', 'P', 'n', 'e', 'H'})
对象的创建方式与集合类型相同。
从列表创建集合
接下来,使用列表作为参数创建类型为 set 和 frozenset 的对象。
mylist = ["A", "B", "C"]
myset = set(mylist)
print(myset)
>> {'B', 'C', 'A'}
myfrozenset = frozenset(mylist)
print(myfrozenset)
>> frozenset({'B', 'C', 'A'})
创建了一个与指定为参数的列表具有相同元素的集合。
从元组创建一个集合
接下来,使用元组作为参数创建类型为 set 和 frozenset 的对象。
mytuple = ("A", "B", "C")
myset = set(mytuple)
print(myset)
>> {'B', 'C', 'A'}
myfrozenset = frozenset(mytuple)
print(myfrozenset)
>> frozenset({'B', 'C', 'A'})
创建了与指定为参数的元组具有相同元素的集合。
从一个range创建一个集合
range 类型是一个对象,它具有从构造函数中指定为自变量的起始编号到结束编号的连续编号。
class range(stop)
class range(start, stop[, step])
它有从开始到结束的连续数值作为元素。如果省略 start,则 0 是起始编号。
使用 range 类型的对象作为参数创建 set 和 frozenset 类型的对象。
myset = set(range(10))
print(myset)
>> {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
myfrozenset = frozenset(range(10))
print(myfrozenset)
>> frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
这样我们就能够创建一个字典,其中包含从 0 到 9 的连续数字作为元素。
我们将解释如何使用内置的 len 函数获取集合的长度(元素数)。
得到集合的长度
内置的 len 函数可以获取作为参数指定的对象的长度和元素个数。如果将集合指定为参数,则可以获得集合中包含的元素数。格式如下。
len(集合)
获取参数中指定的集合中的元素数。set 和 frozenset 类型的集合相同。
len({"Red", "Green", "Blue"})
--> 3
len(frozenset([1, 2, 3, 4, 5]))
--> 5
示例代码
请看下面的示例。
colorset = {"Blue", "Red", "Green", "White", "Black"}
print("要素数は " + str(len(colorset)) + " です。")
>> 要素数は 5 です。
这样我们就能够使用 len 函数获取集合中的元素数。
描述如何向已创建的集合添加元素和从中删除元素。请注意,只有可变集类型可以添加和删除元素。不可变的 frozenset 类型不可能。
向集合中添加一个元素
一种向集合中添加新元素的方法。使用 set 类型上可用的 add 方法。
集合.add(値)
将具有指定值的元素添加到集合中。由于集合中的元素没有顺序,因此无法知道它们将被添加到哪里。
colorset = {"Red", "Green", "Blue"}
colorset.add("White")
print(colorset)
>> {'Green', 'White', 'Blue', 'Red'}
示例代码
请看下面的示例。
colorset = {"Blue", "Red", "Green"}
# 添加"White"
colorset.add("White")
print(colorset)
>> {'Green', 'White', 'Blue', 'Red'}
# 添加"Black"
colorset.add("Black")
print(colorset)
>> {'Black', 'Green', 'Blue', 'Red', 'White'}
这样我们就能够使用 add 方法向集合中添加新元素。
从集合中移除一个元素
如何从集合中删除元素。可以使用 set 类型上可用的 remove、discard 和 pop 方法删除元素。
第一种方法是使用 set 类型上可用的 remove 方法。
集合.remove(値)
从集合中移除具有指定值的元素。如果参数中指定的值在集合中不存在,则会引发 KeyError 错误。
colorset = {"Red", "Green", "Blue"}
colorset.remove("Green")
print(colorset)
>> {'Blue', 'Red'}
colorset.remove("White")
>> Traceback (most recent call last):
>> File "<stdin>", line 1, in <module>
>> KeyError: 'White'
下一个方法是使用 set 类型上可用的 discard 方法。和前面的remove方法的用法几乎是一样的。
集合.discard(値)
从集合中移除具有指定值的元素。与 remove 方法不同,如果指定为参数的值在集合中不存在,则不会发生错误。
colorset = {"Red", "Green", "Blue"}
colorset.discard("Green")
print(colorset)
>> {'Blue', 'Red'}
# 削除しようとした値が存在しない場合でもエラーにはならない
colorset.discard("White")
print(colorset)
>> {'Blue', 'Red'}
最后一种方法是使用 set 类型上可用的 pop 方法。
val = 集合.pop()
pop 方法从集合中删除任何一个元素并返回该元素,但是无法指定要删除的元素。
colorset = {"Red", "Green", "Blue"}
color = colorset.pop()
print(color)
>> Green
print(colorset)
>> {'Blue', 'Red'}
color = colorset.pop()
print(color)
>> Blue
print(colorset)
>> {'Red'}
从集合中删除所有元素
如何从集合中删除所有元素。使用集合类型上可用的清除方法。
集合.clear()
从集合中移除所有元素。
colorset = {"Red", "Green", "Blue"}
colorset.clear()
print(colorset)
>> set()
删除所有元素并不会删除集合本身,它只会导致一个空集合。
我们将讲解如何检查一个集合与其他集合之间的关系,例如一个集合是否等于另一个集合或者一个集合是否是另一个集合的子集。
一个集合是否等于另一个集合 (==,!=)
我们可以使用比较运算符 == 来检查一个集合是否等于另一个集合。您还可以使用比较运算符 != 检查不等式。
集合1 == 集合2
集合1 != 集合2
如果 集合1 的所有元素都在 集合2 中并且 集合2 的所有元素都在 集合1 中,则为真。
set1 = {"A", "B", "C"}
set2 = {"B", "C", "A"}
print(set1 == set2)
>> True
set 类型的对象和 frozenset 类型的对象也可以进行相等比较。
set1 = {"A", "B", "C"}
set2 = frozenset(["B", "A", "C"])
print(set1 == set2)
>> True
该集合是否是另一个集合的子集 (<=)
我们可以使用比较运算符 <= 来测试一个集合是否是另一个集合的子集。
集合1 <= 集合2
如果集合 1 的所有元素都包含在集合 2 中,则称集合 1 是集合 2 的子集。
在以下示例中,set1 是 set2 的子集。相反,set2 不是 set1 的子集。set1 是 set3 的子集,即使 set1 和 set3 相等。
set1 = {"A", "B"}
set2 = {"B", "D", "C", "A"}
set3 = {"B", "A"}
print(set1 <= set2)
>> True
print(set2 <= set1)
>> False
print(set1 <= set3)
>> True
是否是子集也可以使用set类型和frozenset类型提供的issubset方法来判断。
集合1.issubset(集合2)
如果 set1 是 set2 的子集,则为真。
set1 = {"A", "B"}
set2 = {"B", "D", "C", "A"}
set3 = {"A", "B"}
print(set1.issubset(set2))
>> True
print(set2.issubset(set1))
>> False
print(set1.issubset(set3))
>> True
该集合是否是另一个集合的真子集 (<)
我们可以使用比较运算符 < 来检查一个集合是否是另一个集合的真子集。
集合1 < 集合2
如果集合 1 的所有元素都包含在集合2 中并且集合1 和集合2 不相等,则称集合1 是集合2 的真子集。
在下面的示例中,set1 是 set2 的真子集。相反,set2 不是 set1 的真子集。如果 set1 和 set3 相等,它也不是真子集。
set1 = {"A", "B"}
set2 = {"B", "D", "C", "A"}
set3 = {"A", "B"}
print(set1 < set2)
>> True
print(set2 < set1)
>> False
print(set1 < set3)
>> False
该集合是否是另一个集合的超集 (>=)
我们可以使用 >= 比较运算符测试一个集合是否是另一个集合的超集。
集合1 >= 集合2
如果集合 2 的所有元素都包含在集合 1 中,则集合 1 被称为集合 2 的超集合。
在以下示例中,set1 不是 set2 的超集合,但 set2 是 set1 的超集合。set1 是 set3 的超集合,即使 set1 和 set3 相等。
set1 = {"A", "B"}
set2 = {"B", "D", "C", "A"}
set3 = {"B", "A"}
print(set1 >= set2)
>> False
print(set2 >= set1)
>> True
print(set1 >= set3)
>> True
print(set3 >= set1)
>> True
也可以通过set类型和frozenset类型提供的issuperset方法来判断是否是超集合。
集合1.issuperset(集合2)
如果 set1 是 set2 的超集则为真。
set1 = {"A", "B"}
set2 = {"B", "D", "C", "A"}
set3 = {"A", "B"}
print(set1.issuperset(set2))
>> False
print(set2.issuperset(set1))
>> True
print(set1.issuperset(set3))
>> True
print(set3.issuperset(set1))
>> True
该集合是否是另一个集合的真正超集合 (>)
我们可以使用 > 比较运算符测试一个集合是否是另一个集合的真正超集合。
集合1 > 集合2
如果集合 2 的所有元素都包含在集合 1 中并且集合 1 和集合 2 不相等,则集合 1 被称为集合 2 的真正超集。
在以下示例中,set1 不是 set2 的真正超集,但 set2 是 set1 的真正超集。如果 set1 和 set3 相等,它也不是真正的超集。
set1 = {"A", "B"}
set2 = {"B", "D", "C", "A"}
set3 = {"A", "B"}
print(set1 > set2)
>> False
print(set2 > set1)
>> True
print(set1 > set3)
>> False
该集合是否与其他集合不相交
我们可以使用 set 和 frozenset 类型提供的 isdisjoint 方法检查一个集合是否与其他集合不相交。
集合1.isdisjoint(集合2)
如果集合 1 和集合 2 没有相同的元素,则称集合 1 与集合 2 不相交。
在下面的示例中,set1 是不相交的,因为 set2 没有共同的元素,但是 set1 和 set3 以及 set2 和 set3 是不相交的,因为它们有共同的元素。
set1 = {"A", "B"}
set2 = {"C", "D", "E"}
set3 = {"A", "C"}
print(set1.isdisjoint(set2))
>> True
print(set1.isdisjoint(set3))
>> False
print(set2.isdisjoint(set3))
>> False
我们将讲解如何执行集合和集合运算,以及如何分别求并集、交集、差集和对称差集。
求集合的和
并集是包含在两个集合中至少一个集合中的一组元素。
要和并集合,请使用 | 运算符, 如果是set 和 frozenset 类型,请使用 union 方法。
集合 = 集合1 | 集合2
集合 = 集合1.union(集合2)
两者都将返回 set1 和 set2 的并集合。
具体写如下。
set1 = {"A", "B", "C", "D"}
set2 = {"C", "D", "E", "F"}
print(set1 | set2)
>> {'B', 'D', 'E', 'C', 'F', 'A'}
print(set1.union(set2))
>> {'B', 'D', 'E', 'C', 'F', 'A'}
您还可以找到三个或更多集合的并集。(交点和差点也是一样,后面再说。)
集合 = 集合1 | 集合2 | 集合3 | ...
集合 = 集合1.union(集合2, 集合3, ...)
具体写如下。
set1 = {"A", "B", "C", "D"}
set2 = {"C", "D", "E", "F"}
set3 = {"A", "C", "E", "G"}
print(set1 | set2 | set3)
>> {'G', 'B', 'D', 'E', 'C', 'F', 'A'}
在第一个集合中保持并集不变,而不是将其作为一个新集合。使用 |= 运算符或使用集合类型提供的更新方法。
集合1 |= 集合2
集合1.update(集合2)
具体写如下。
set1 = {"A", "B", "C", "D"}
set2 = {"C", "D", "E", "F"}
set1.update(set2)
print(set1)
>> {'B', 'D', 'E', 'C', 'F', 'A'}
求交集合
交集合是包含在两个集合中的元素集。
要求交集合,请使用运算符& 或,如果是set 和 frozenset 类型,请使用intersection。
集合 = 集合1 & 集合2
集合 = 集合1.intersection(集合2)
两者都将返回set1 和 set2 的交集合。
具体写如下。
set1 = {"A", "B", "C", "D"}
set2 = {"C", "D", "E", "F"}
print(set1 & set2)
>> {'D', 'C'}
set1.intersection(set2)
>> {'D', 'C'}
在第一个集合中保持交集不变,而不是将其作为一个新集合。使用 &= 运算符或集合类型提供的 intersection_update 方法。
集合1 &= 集合2
集合1.intersection_update(集合2)
具体写如下。
set1 = {"A", "B", "C", "D"}
set2 = {"C", "D", "E", "F"}
set1.intersection_update(set2)
print(set1)
>> {'D', 'C'}
求集合差
集合差是集合 1 中,但不在集合 2 中的元素集合。
要求集合差异,请使用 – 运算符,如果是 set 和 frozenset 类型,请使用difference。
集合 = 集合1 - 集合2
集合 = 集合1.difference(集合2)
两者都返回一个新集合作为 set1 和 set2 的差异集。
具体写如下。
set1 = {"A", "B", "C", "D"}
set2 = {"C", "D", "E", "F"}
print(set1 - set2)
>> {'A', 'B'}
print(set1.difference(set2))
>> {'A', 'B'}
在第一组中保持差异设置不变,而不是将其作为新的一组。使用运算符 -= 或使用集合类型提供的 difference_update 方法。
集合1 -= 集合2
集合1.difference_update(集合2)
具体写如下。
set1 = {"A", "B", "C", "D"}
set2 = {"C", "D", "E", "F"}
set1 -= set2
print(set1)
>> {'B', 'A'}
求对称差分集和
对称差分集是仅包含在两个集合中的一个元素中的一组元素。
要求对称差异,请使用运算符 ^ ,如果是 set 和 frozenset 类型,请使用symmetric_difference 。
集合 = 集合1 ^ 集合2
集合 = 集合1.symmetric_difference(集合2)
两者都将新集合作为 set1 和 set2 的对称差集返回。
具体写如下。
set1 = {"A", "B", "C", "D"}
set2 = {"C", "D", "E", "F"}
print(set1 ^ set2)
>> {'F', 'B', 'E', 'A'}
print(set1.symmetric_difference(set2))
>> {'F', 'B', 'E', 'A'}
在第一个集合中保持交集不变,而不是将其作为一个新集合。使用运算符 ^= 或使用集合类型提供的 symmetric_difference_update 方法。
集合1 ^= 集合2
集合1.symmetric_difference_update(集合2)
具体写如下。
set1 = {"A", "B", "C", "D"}
set2 = {"C", "D", "E", "F"}
set1 ^= set2
print(set1)
>> {'B', 'E', 'F', 'A'}
这一节,我们讲解一下如何检查创建的集合是否包含与指定值相同的元素。使用 in 运算符检查是否包含元素。
检查是否包含与指定值具有相同值的元素
使用 in 运算符或 not in 运算符检查集合中是否包含具有指定值的元素。
値 in 集合
値 not in 集合
如果集合中的任何元素具有与指定值相同的值,则 in 运算符返回 True。否则为假。相反,如果集合的元素中存在与指定值相同的元素,则 not in 运算符返回 False。如果有的话是真的。
首先尝试设置类型。具体写如下。
myset = {"A", "B", "C"}
print("A" in myset)
>> True
print("D" in myset)
>> False
由于我们使用 in 运算符,如果指定值在集合中,它将返回 True,否则返回 False。
现在试试 frozenset 类型。
myfrozenset = frozenset(["A", "B", "C"])
print("A" in myfrozenset)
>> True
print("D" in myfrozenset)
>> False
frozenset 类型与集合类型相同。