python 空集合_Python的内置对象:集合

Python的内置对象:集合

摘要: 了解Python内置对象集合:它们是什么,如何创建它们,何时使用它们,内置函数,以及集合之间的关系操作。


原文:https://towardsdatascience.com/python-sets-and-set-theory-2ace093d1607

原文作者:Michael Galarnyk

翻译:老齐

集合 vs 列表和元组

列表和元组都是Python内置数据类型,它们按序列存储值。集合是另一种Python内置数据类型,它也可以存储值。主要的区别在于,集合与列表或元组不同,不能重复项,也不能存储无法排序的值。

Python集合的优点

由于集合不能有重复项,因此集合对于有效地从列表或元组中删除重复值以及执行常见的数学操作(如并集和交集)非常有用。

本文将向你介绍一些有关Python集合的内容:

  • 如何创建空集合和非空集合。
  • 如何增加和删除集合中的值。
  • 如何有效地将集合用于成员检测和从列表中删除重复值等任务。
  • 如何执行常见的集合运算,如并集、交集、差集和对称差集。
  • 可变集合和不可变集合的区别

好了,我们开始吧。

创建集合

集合是中的值必须是唯一的、不可变的,且是无序的。

可以使用set()创建空集合。

emptySet = set()

为了创建一个带有值的集合,可以将列表传递给set()

dataScientist = set(['Python', 'R', 'SQL', 'Git', 'Tableau', 'SAS']) dataEngineer = set(['Python', 'Java', 'Scala', 'Git', 'SQL', 'Hadoop'])

python 空集合_Python的内置对象:集合_第1张图片

如果查看上面dataScientist和dataEngineer变量,请注意集合中的值并没有按照添加的顺序排列。这是因为集合是无序的。

包含值的集合也可以使用大括号创建。

dataScientist = {'Python', 'R', 'SQL', 'Git', 'Tableau', 'SAS'} dataEngineer = {'Python', 'Java', 'Scala', 'Git', 'SQL', 'Hadoop'}

请记住,大括号只能用于创建含有值的集合。下图显示,使用不带值的大括号是创建字典而不是集合。

python 空集合_Python的内置对象:集合_第2张图片

添加和移除集合的值

要添加和移除值,首先必须创建集合。

# Initialize set with values graphicDesigner = {'InDesign', 'Photoshop', 'Acrobat', 'Premiere', 'Bridge'}

向集合中添加值

你可以使用add方法向集合添加值。

graphicDesigner.add('Illustrator')

python 空集合_Python的内置对象:集合_第3张图片

必须注意的是,你只能将不可变的值(如字符串或元组)添加到集合中。例如,如果你尝试将列表添加到集合中,则会收到TypeError这样的提醒。

graphicDesigner.add(['Powerpoint', 'Blender'])

有几种方法可以从集合中移除值。

**方法1:**你可以使用remove方法从集合中移除值。

graphicDesigner.remove('Illustrator')

python 空集合_Python的内置对象:集合_第4张图片

此方法的缺点是,如果尝试删除不在集合中的值,则会得到KeyError这样的提示。

python 空集合_Python的内置对象:集合_第5张图片

**方法2:**可以使用discard方法从集合中移除值。

graphicDesigner.discard('Premiere')

python 空集合_Python的内置对象:集合_第6张图片

remove方法相比,这种方法的好处是:如果尝试删除不属于集合的值,则不会得到keyerror。如果你熟悉字典,你可能会发现它的工作方式与字典对象的get方法类似。

**方法3:**还可以使用pop方法从集合中移除值并返回任意值。

graphicDesigner.pop()

python 空集合_Python的内置对象:集合_第7张图片

需要注意的是,如果集合为空,该方法将导致KeyError。

从集合中移除所有值

你可以使用clear方法从集合中移除所有值。

graphicDesigner.clear()

python 空集合_Python的内置对象:集合_第8张图片

遍历集合

与许多Python内置数据类型一样,可以遍历一个集合。

# Initialize a set dataScientist = {'Python', 'R', 'SQL', 'Git', 'Tableau', 'SAS'}for skill in dataScientist:     print(skill)

python 空集合_Python的内置对象:集合_第9张图片

打印dataScientist中的每个值,请注意,在集合中打印的值不是按照它们被添加的顺序。这是因为集合是无序的。

将集合转换为有序值

本文强调集合是无序的。如果你发现需要以有序形式从集合中获取值,可以使用sorted函数输出有序的列表。

type(sorted(dataScientist))

048b5f24c26e7a11b25e2b9cdb5119e0.png

下面的代码按字母降序(本例中为Z-A)输出集合dataScientist中的值。

sorted(dataScientist, reverse = True)

python 空集合_Python的内置对象:集合_第10张图片

从列表中删除重复项

本节的部分内容先前在《18个最常见的Python列表问题》中探讨过,但必须强调的是,集合是从列表中删除重复项的最快方法。为了说明这一点,让我们研究两种方法之间的性能差异。

**方法1:**使用集合从列表中删除重复项。

print(list(set([1, 2, 3, 1, 7])))

**方法2:**使用列表解析从列表中删除重复项。

def remove_duplicates(original):    unique = []    [unique.append(n) for n in original if n not in unique]    return (unique)    print(remove_duplicates([1, 2, 3, 1, 7]))

可以使用timeit库测量性能差异,该库允许你对Python代码计时。下面的代码为每个方法运行代码10000次,并输出它所用的总时间(秒)。

import timeit# Approach 1: Execution time print(timeit.timeit('list(set([1, 2, 3, 1, 7]))', number=10000))# Approach 2: Execution timeprint(timeit.timeit('remove_duplicates([1, 2, 3, 1, 7])', globals=globals(), number=10000))

python 空集合_Python的内置对象:集合_第11张图片

比较这两种方法,可以发现使用集合来移除重复项更为有效。虽然这看起来只是时间上的一个小的差异,但如果你有非常大的列表,它可以为你节省很多时间。

集合运算

集合在Python中的一个常见用法是进行数学运算,如并集、交集、差集和对称差集。下图显示了集合A和B上的两个数学运算。每个维恩图的红色部分是给定的集合运算的结果集。

python 空集合_Python的内置对象:集合_第12张图片

Python集合有允许你执行这些数学操作的方法,以及提供等价结果的操作符。

在研究这些方法之前,让我们先创建两个集合dataScientist和dataEngineer。

dataScientist = set(['Python', 'R', 'SQL', 'Git', 'Tableau', 'SAS'])dataEngineer = set(['Python', 'Java', 'Scala', 'Git', 'SQL', 'Hadoop'])

并集

集合dataScientist和dataEngineer的所有值组成的集合称为它们的并集,可以使用一个集合对象的union方法找出两个集合中的所有的惟一值。

# set built-in function uniondataScientist.union(dataEngineer)# Equivalent Result dataScientist | dataEngineer

6a224ce6ce7e90249e14de1da0ffaf63.png

unino方法的返回值用可视化的方法表示就是下面的维恩图的红色部分。

python 空集合_Python的内置对象:集合_第13张图片

交集

两个集合dataScientist和dataEngineer的交集,表示为 dataScientist ∩ dataEngineer。这个交集包含了所有既属于dataScientist又属于dataEngineer的值。

# Intersection operationdataScientist.intersection(dataEngineer)# Equivalent ResultdataScientist & dataEngineer

python 空集合_Python的内置对象:集合_第14张图片

交集用可视化的方式表示为下面的维恩图的红色部分。

python 空集合_Python的内置对象:集合_第15张图片

你可能会遇到这样一个情况:希望确保两个集合没有共同的值。换句话说,你想让两个集合的交集为空。这两个集合称为不相交集合。可以使用isdisjoint方法测试不相交集。

# Initialize a setgraphicDesigner = {'Illustrator', 'InDesign', 'Photoshop'}# These sets have elements in common so it would return FalsedataScientist.isdisjoint(dataEngineer)# These sets have no elements in common so it would return TruedataScientist.isdisjoint(graphicDesigner)

python 空集合_Python的内置对象:集合_第16张图片

你可能注意到,在下面的维恩图所显示的交集中,不相交集合dataScientist和graphicDesigner没有共同的值。

python 空集合_Python的内置对象:集合_第17张图片

差集

两个集合dataScientist和dataEngineer之间的差集是所有属于dataScientist 而不属于dataEngineer的值的集合。

# Difference OperationdataScientist.difference(dataEngineer)# Equivalent ResultdataScientist - dataEngineer

python 空集合_Python的内置对象:集合_第18张图片

用可视化的方式表示差集,为下面的维恩图的红色部分。

python 空集合_Python的内置对象:集合_第19张图片

对称差集

两个集合dataScientist和dataEnngineer的对称差集,表示为dataScientist △ dataEngineer,是属于这两个集合的其中之一的所有值的集合,但这些值不同时属于这两个集合。

# Symmetric Difference OperationdataScientist.symmetric_difference(dataEngineer)# Equivalent ResultdataScientist ^ dataEngineer

a6cca4be93d5c5d47a599d69469875c7.png

对称差集可以用可视化方式表示为下面的维恩图的红色部分。

python 空集合_Python的内置对象:集合_第20张图片

集合解析

你以前可能已经学习过列表解析、字典解析和生成器推解析。除了这些,还有集合解析,其方式如下:

{skill for skill in ['SQL', 'SQL', 'PYTHON', 'PYTHON']}

0d934e7d54a4154f1d3a85a08fe8ee93.png

上面的输出是2个值的集合,因为集合不能有重复值。

使用集合解析背后的想法是让你用代码编写和推理,就像动手做数学一样。

{skill for skill in ['GIT', 'PYTHON', 'SQL'] if skill not in {'GIT', 'PYTHON', 'JAVA'}}

fa31f3ee1b837fbf6b8e3d55d5c9948c.png

上面的代码类似于你之前所了解的差集。只是看起来有点不同。

成员检测

成员检测即检查某个特定元素是否包含在一个序列中,例如字符串、列表、元组或集合。在Python中使用集合的一个主要优点是,它对于成员检测是高度优化的。例如,集合比列表更有效地进行成员检测。这是因为集合中的成员检测的平均时间复杂度与列表相比,是 O(1) vs O(n)。

下面的代码显示了一个使用列表的成员检测。

# Initialize a listpossibleList = ['Python', 'R', 'SQL', 'Git', 'Tableau', 'SAS', 'Java', 'Spark', 'Scala']# Membership test'Python' in possibleList

20013a2eac86b5746e0398b18bdecd83.png

使用集合也可以做类似的事情,更有效率。

# Initialize a setpossibleSet = {'Python', 'R', 'SQL', 'Git', 'Tableau', 'SAS', 'Java', 'Spark', 'Scala'}# Membership test'Python' in possibleSet

python 空集合_Python的内置对象:集合_第21张图片

因为possibleSet是一个集合,而PythonpossibleSet的一个值,所以可以将其表示为'Python' ∈ possibleSet

如果你有一个不属于这个集合的值,比如'Fortran',它将被表示为 'Fortran' ∉ possibleSet

子集

理解成员关系的一个实际应用是子集。

我们先创建两个集合。

possibleSkills = {'Python', 'R', 'SQL', 'Git', 'Tableau', 'SAS'} mySkills = {'Python', 'R'}

如果集合mySkills的每个值也是possibleSkills的值,那么mySkills 就是possibleSkills的一个子集,在数学上写作mySkills ⊆ possibleSkills

你可以使用issubset方法检查一个集合是否是另一个集合的子集。

mySkills.issubset(possibleSkills)

ba00d88af8621b61c8ad9219b65440e1.png

由于该方法在本例中返回True,所以它是一个子集。在下面的维恩图中,请注意:集合mySkills的每个值也是集合possibleSkills的一个值。

python 空集合_Python的内置对象:集合_第22张图片

不可变集合

你已经学习过嵌套列表和元组。

# Nested Lists and TuplesnestedLists = [['the', 12], ['to', 11], ['of', 9], ['and', 7], ['that', 6]]nestedTuples = (('the', 12), ('to', 11), ('of', 9), ('and', 7), ('that', 6))

python 空集合_Python的内置对象:集合_第23张图片

嵌套集合的问题是,你通常不能使用嵌套集合,因为集合不能包括可变值。

python 空集合_Python的内置对象:集合_第24张图片

只有在一种情况下,你可能希望使用不可变集合。不可变集合与集合非常相似,只是它不可变。

你可以使用frozenset()生成一个不可变集合。

# Initialize a frozensetimmutableSet = frozenset()

python 空集合_Python的内置对象:集合_第25张图片

如果使用不可变集合,则可以生成嵌套集合。

nestedSets = set([frozenset()])

python 空集合_Python的内置对象:集合_第26张图片

重要的是要记住,不可变集合的一个主要缺点是:由于它是不可变的,这就意味着不能添加或删除值。

结论

Python集合对于有效地从序列(如列表)中移除重复值以及执行常见的数学操作(如并集和交集)非常有用。人们经常遇到的一些挑战是何时使用各种数据类型。例如,如果你不确定何时使用字典比使用集合有利,我建议你认真阅读 《Python大学实用教程》 或者 《跟老齐学Python:轻松入门》 ,这两本书都是由电子工业出版社出版,书中的详细讲解和案例能够让你理解各种对象类型的应用场景。

python 空集合_Python的内置对象:集合_第27张图片

python 空集合_Python的内置对象:集合_第28张图片

(点击下面的“阅读原文”,京东双十一优惠购买上述图书)

你可能感兴趣的:(python,空集合)