Python 集合类型 set,frozenset 使用说明

我被代码海扁署名-非商业-禁演绎
阅读 10:41·字数 3207·发布 
Bilibili 空间
关注 960

Python 集合类型

Python 的集合类型set(集合)和frozenset(冻结集合),与 Python 序列类型有众多相似之处,但集合类型可有效的用于数学集合运算,比如,计算两个集合的并集。

Python 集合中的元素是不可重复的

集合中的元素需要确保自己在集合中的唯一性,通过对象的__eq__方法,以及__hash__方法返回的哈希值,可以判断一个元素是否与另一个元素重复,重复的多余元素将从集合中移除。

Python 集合中的元素是无序的

在某些情况下,Python 集合会进行自动排序,比如,书写{100,102,101}创建一个集合,该集合可能变为{100,101,102}。这种自动排序拥有很大的“随机性”,因此 Python 集合是无序的,比如,书写{100,102,101,1,96,95,94}创建集合,结果可能变为{96,1,100,101,102,94,95}

Python 对象的 __hash__ 和 __eq__ 方法

对象的__hash__方法返回对象对应的哈希值,在 Python 中,该值应该是一个整数。对象的__eq__方法用于判断对象之间是否为相等的关系。

Python set,frozenset 类型

同样作为 Python 的集合类型,frozenset是不可变的,set是可变的,其支持的功能和操作也更多。无论是set还是frozenset,都可以使用构造器来创建实例。

set([iterable], /)
frozenset([iterable], /)

iterable 参数

iterable参数是一个迭代器对象,迭代器中的元素将包含在集合中。如果未指定,则会得到一个空集合。

对于set类型,除了构造器,还可以使用{}来创建实例,{}中为集合中包含的元素,元素之间使用,进行分隔。

另外,在{}中使用推导式可以进行更为复杂的操作,推导式的格式为y for x in iterable,其中,iterable为迭代器对象,x为迭代器中的元素,y为一个表达式,通常会通过x产生新的值。

不能使用 {} 来创建空的 Python 集合

需要指出,你不能使用{}来创建空集合,因为{}会返回一个空的字典(dict)对象。要创建空集合,可以书写set()

set()
set()
{1, 2, 3}
{1, 2, 3}
frozenset([1, 2, 3])
frozenset({1, 2, 3})

获取 Python 集合,冻结集合中元素的个数

使用len函数,可以获取 Python 集合,冻结集合的元素个数,比如,len({3,2,2,1,1})的运算结果为3

判断 Python 集合,冻结集合是否存在某个元素

使用x in sx not in s,可以判断 Python 集合,冻结集合中是否存在或不存在某个元素,x为需要判断的元素,s为集合对象。

100 in {100, 101, 102}
True

判断 Python 集合,冻结集合之间的关系

Python 提供了如下方法,用于判断集合或冻结集合之间的关系。

isdisjoint方法用于判断集合与指定目标的交集是否空,即集合中的元素是否均未在目标中出现,如果是则返回True,否则返回False,这里的目标是一个迭代器对象。

issubset方法用于判断集合是否为指定目标的子集,即集合中的元素是否均在目标中出现,如果是则返回True,否则返回False,这里的目标是一个迭代器对象。此外,使用运算符<=可以实现相同的效果,他会判断左边集合是否为右边集合的子集。

运算符<用于判断左边集合是否为右边集合的真子集,即左边集合的元素均在右边集合中出现,且右边集合拥有左边集合不存在的元素。

issuperset方法用于判断集合是否为指定目标的超集,即目标包含的元素均在集合中出现,如果是则返回True,否则返回False,这里的目标是一个迭代器对象。此外,使用运算符>=可以实现相同的效果,他会判断左边集合是否为右边集合的超集。

运算符>用于判断左边集合是否为右边集合的真超集,即右边集合的元素均在左边集合中出现,且左边集合拥有右边集合不存在的元素。

运算符==用于判断左边集合是否与右边集合相等,即右边集合的元素均在左边集合中出现,左边集合的元素也均在右边集合中出现。

isdisjoint(other, /)
issubset(other, /)
issuperset(other, /)

other 参数

other参数为参与关系判断的迭代器对象。

{3,2,1}.isdisjoint((4,))
True
{3,2,1}<={1,2,3}
True
{3,2,1}.issuperset((1,2,3))
True
{3,2,1}>{1,2,3}
False
set() == set()
True

计算 Python 集合,冻结集合

Python 提供了如下方法,用于集合或冻结集合的计算。

union方法将计算并返回一个并集集合,其类型与目标集合的类型相同,包含了目标集合与迭代器中的所有元素。此外,使用运算符|联接多个集合,可以产生相同的效果,你会得到一个新集合,其类型与运算符|左边的集合的类型相同。

intersection方法将计算并返回一个交集集合,其类型与目标集合的类型相同,包含了即存在于目标集合,又存在于迭代器的元素。此外,使用运算符&联接多个集合,可以产生相同的效果,你会得到一个新集合,其类型与运算符&左边的集合的类型相同,集合中的元素即存在于运算符&左边的集合,又存在于运算符&右边的集合。

difference方法将计算并返回一个差集集合,其类型与目标集合的类型相同,包含了存在于目标集合,但不存在于迭代器的元素。此外,使用运算符-联接多个集合,可以产生相同的效果,你会得到一个新集合,其类型与运算符-左边的集合的类型相同,集合中的元素存在于运算符-左边的集合,但不存在于运算符-右边的集合。

symmetric_difference方法将计算并返回一个对称差集集合,其类型与目标集合的类型相同,包含了仅存在于目标集合,或仅存在于迭代器的元素。此外,使用运算符^联接多个集合,可以产生相同的效果,你会得到一个新集合,其类型与运算符^左边的集合的类型相同,集合中的元素或仅存在于运算符^左边的集合,或仅存在于运算符^右边的集合。

union(*other)
intersection(*other)
difference(*other)
symmetric_difference(other, /)

other 参数

other参数为参与计算的迭代器对象。

{1}.union((3,4,1))
{1, 3, 4}
{1} | {2,1} | {2, 3}
{1, 2, 3}
frozenset({1, 2, 3}).intersection({1})
frozenset({1})
{1, 2, 3} & set()
set()
{1, 2, 3}.difference([1], [3])
{2}
frozenset({1, 2, 3}) ^ {2, 3, 4}
frozenset({1, 4})

复制 Python 集合,冻结集合

使用 Python 集合,冻结集合的copy方法,你可以对集合进行阴影复制,复制的集合与被复制的集合互不影响,但两个集合中的元素可能会保持对同一对象的引用。

a = {1, 2, 3}
b = a.copy()
b.add(4)
a
{1, 2, 3}
b
{1, 2, 3, 4}

更新 Python 集合

Python 提供了以下方法,用于集合(set)的更新,这表示集合本身会被修改。

update方法会尝试把迭代器中的所有元素添加至集合,重复的元素将被忽略。此外,使用运算符|=可以产生相同的效果,他会把右边集合中的元素添加至左边集合。

intersection_update方法会更新集合,所有未在迭代器中出现的元素将被移除。此外,使用运算符&=可以产生相同的效果,他会把所有未出现在右边集合的元素,从左边集合中移除。

difference_update方法会更新集合,所有在迭代器中出现的元素将被移除。此外,使用运算符-=可以产生相同的效果,他会把所有出现在右边集合的元素,从左边集合中移除。

symmetric_difference方法计算所有未同时出现在集合和迭代器中的元素,这些元素最终成为集合的所有元素。此外,使用运算符^=可以产生相同的效果,他会计算所有未同时出现在左边集合和右边集合的元素,并确保他们成为左边集合的所有元素。

update(*other)
intersection_update(*other)
difference_update(*other)
symmetric_difference_update(other, /)

other 参数

other参数为参与更新的迭代器对象。

s = {1, 2, 3, 4}
s.update((1, 2), (5, 6))
s
{1, 2, 3, 4, 5, 6}
s &= {1, 6} | {5, 2, 4}
s
{1, 2, 4, 5, 6}
s.difference_update({4} | {5})
s
{1, 2, 6}
s ^= {2, 6, 7}
s
{1, 7}

为 Python 集合添加元素

使用set类型的add方法,你可以为集合添加一个元素。

add(elem, /)

elem 参数

elem参数表示需要添加的元素。

s = set()
s.add(1)
s
{1}

删除 Python 集合中的元素

对于删除元素,Python 的set类型提供了如下方法。

remove方法用于将指定元素从集合中删除,如果元素不存在,则会引发异常KeyError

discard方法用于将指定元素从集合中删除,但他不会像remove方法一样引发异常。

pop方法用于删除并返回集合中的任意一个元素,如果是空集合,则将引发异常KeyError

clear方用于删除集合中的所有元素。

Python 集合的 pop 方法是否随机返回元素?

虽然,在一些情况下pop方法会固定返回集合的第一个元素,但你依然可以认为pop方法随机返回元素,因为元素的位置具有“随机性”。

remove(elem, /)
discard(elem, /)

elem 参数

elem参数为需要删除的元素。

s = {1, 2, 3, 4, 5, 6}
s.remove(3)
s
{1, 2, 4, 5, 6}
s.discard(3)
s
{1, 2, 4, 5, 6}
s.pop()
1
s.clear()
s
set()