# Python 集 > 原文: [https://javabeginnerstutorial.com/python-tutorial/python-3-set-2/](https://javabeginnerstutorial.com/python-tutorial/python-3-set-2/) 在上一篇文章中,我们讨论了 [Python 列表](https://javabeginnerstutorial.com/python-tutorial/python-list-2/)。但是 Python 3 `Set`是什么? 集合是*唯一*项目的*无序*集合。 **无序**表示这种类型的集合不允许建立索引,并且您无法像列表或元组那样通过索引访问它们的元素。 **唯一**表示即使将同一元素多次放入集合中,每个元素在集合中也只有一次。 自然,您可以像使用列表或元组一样将字符串中的类型混合在一起。 ## 创建 Python 集 有一些方法可以创建集合。 基本版本是列出花括号(`{}`)之间的所有元素。 但是,最常见的用法是当您要从列表中删除重复项时。 在这种情况下,您可以将列表转换为集合,然后再次返回列表。 这将从集合的中间用法中将重复项从列表中删除,您将再次拥有列表。 为此,使用`set`函数,该函数需要一个可迭代的参数。 ```py >>> A = {1,2,3,4,5} >>> A {1, 2, 3, 4, 5} >>> B = set((1,2,3,4,5)) >>> B {1, 2, 3, 4, 5} >>> C = set([1,2,5,4,3,4,5]) >>> C {1, 2, 3, 4, 5} >>> D = set(1,2,3,4,5) Traceback (most recent call last): File "", line 1, in TypeError: set expected at most 1 arguments, got 5 >>> D = set(1) Traceback (most recent call last): File "", line 1, in TypeError: 'int' object is not iterable ``` 如您所见,您不能将可变数量的参数作为参数或不可迭代的参数添加。 **但是!** 您可以传递字符串作为 set 函数的参数,因为(您可能还记得),字符串是 Python 中的字符列表。 在这种情况下,字符串将拆分为字符,并且每个字符在集合中仅存储一次。 ```py >>> D = set("Spam! Spam! Spam!") >>> D {'p', 'm', ' ', 'a', 'S', '!'} ``` 而且因为我已经提到过,您可以使用集合来过滤列表的重复项,因此这里是示例: ```py >>> l = [1,2,3,2,1,2,3,4,5,6,5,6,4,7,8,3,2,1,3,4,5,6] >>> l [1, 2, 3, 2, 1, 2, 3, 4, 5, 6, 5, 6, 4, 7, 8, 3, 2, 1, 3, 4, 5, 6] >>> l = list(set(l)) >>> l [1, 2, 3, 4, 5, 6, 7, 8] ``` 此示例首先将`l`转换为一个集合,该集合将删除所有重复的元素,然后将集合折回为允许进行索引的列表。 我在进行网站抓取并亲自编写抓取逻辑时使用了这种类型的过滤。 ## 更改 Python 集 集是可变的(不是一成不变的),因此您可以更改它们的元素。 更改意味着添加和删除元素。 由于集合不支持索引,因此无法像列表一样更改给定索引的元素。 试想一下,如果您可以更改一组中的一个元素,将会发生什么? 必须每次在后台运行某种机制来过滤出可能的重复元素。 那将是无稽之谈,并且会使使用`set`非常缓慢。 这意味着我们仅需添加和删除元素。 与列表不同,您不能使用加法运算符(加号`+`)来扩展集合。 您必须使用`add()`或`update()`。 这两种方法的区别在于参数的数量和类型。 ```py >>> A = {1} >>> A {1} >>> A.add(2) >>> A {1, 2} >>> A.add({3}) Traceback (most recent call last): File "", line 1, in TypeError: unhashable type: 'set' >>> A.add((3)) >>> A {1, 2, 3} >>> A.add((3,4)) >>> A {1, 2, 3, (3, 4)} >>> A.add(5,6) Traceback (most recent call last): File "", line 1, in TypeError: add() takes exactly one argument (2 given) >>> A.add([5,6],(7)) Traceback (most recent call last): File "", line 1, in TypeError: add() takes exactly one argument (2 given) >>> A.update([5,6],(7)) Traceback (most recent call last): File "", line 1, in TypeError: 'int' object is not iterable >>> A.update([5,6],(7,)) >>> A {1, 2, 3, 5, 6, 7, (3, 4)} >>> A.update([1,2,3,4]) >>> A {1, 2, 3, 4, 5, 6, 7, (3, 4)} ``` 如上例所示,您需要为`add`函数提供一个不可变的元素(就像创建集合时一样)。 `update`函数采用多个参数,这些参数必须是集合。 这些集合是不可变的,也不必只是必须是集合。 在所有情况下,都避免重复。 ## 移除元素 有时您需要根据各种条件删除元素。 在这种情况下,您有一些方法在每种情况下的行为都会略有不同。 ```py >>> A = {1, 2, 3, 4, 5, 6, 7, 8, 9, (3, 4)} >>> A {1, 2, 3, 4, 5, 6, 7, 8, 9, (3, 4)} >>> A.remove((3,4)) >>> A {1, 2, 3, 4, 5, 6, 7, 8, 9} >>> A.remove(3,4) Traceback (most recent call last): File "", line 1, in TypeError: remove() takes exactly one argument (2 given) >>> A.remove(5) >>> A {1, 2, 3, 4, 6, 7, 8, 9} >>> A.remove(5) Traceback (most recent call last): File "", line 1, in KeyError: 5 leanpub-start-insert >>> A.discard(5) leanpub-end-insert >>> n = A.pop() >>> n 1 >>> A {2, 3, 4, 6, 7, 8, 9} >>> A.clear() >>> A set() >>> A.pop() Traceback (most recent call last): File "", line 1, in KeyError: 'pop from an empty set' ``` 如您所见,`remove`函数仅使用一个参数,而不是更多。 即使使用`A.remove((3,4))`,我们也只提供一个元素—元组。 如果要添加多个元素,则会出现`TypeError`。 如果该键不存在于集合中,则在尝试使用`remove`摆脱键时会出现`KeyError`。 但是,如果给定密钥不在集合中,则丢弃不会产生任何噪音。 它默默地发出有关该应用的通知,该应用不知道集合的状态,因此不再打扰。 `pop`函数(就像我们已经知道的那样)采用集合中的一个元素,将其删除并返回。 如果集合为空,则将再次收到`KeyError`。 似乎在使用`pop`时总是返回第一个元素,但是您不知道集合中元素的顺序。 实现可能会改变它们存储元素的方式并记住:如果您自己运行应用,则不会看到集合中的元素。 ## 冻结集 冻结集是一种特殊的集,它具有与普通集相同的属性,但是您不能更改其元素。 这意味着,一旦创建了冻结集,就必须遵守分配给它的值(自然地,重新分配变量始终是一种解决方案)。 我们来看一些示例。 ```py >>> A = frozenset([1,2,3,4,5]) >>> B = {2,4,6,8,10} >>> A | B frozenset({1, 2, 3, 4, 5, 6, 8, 10}) >>> A & B frozenset({2, 4}) >>> A.add(6) Traceback (most recent call last): File "", line 1, in AttributeError: 'frozenset' object has no attribute 'add' >>> A += {6} Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for +=: 'frozenset' and 'set' >>> A += frozenset({6}) Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for +=: 'frozenset' and 'frozenset' ``` 如您在上面的示例中看到的那样,没有方法可以将新元素添加到冻结集中。 删除或更改元素也是如此。 好吧,`frozenset`被冻结了,仅供使用。 ### 参考文献 * [官方文档](https://docs.python.org/3/tutorial/datastructures.html)