Python中的集合

本文介绍了Python集合的创建、无序和唯一性特点,以及去重功能。讨论了集合的访问方式,包括使用in和notin判断元素存在,以及通过迭代访问。文章还详细阐述了集合的常用方法,如复制、检测子集和超集、并集、交集、差集和对称差集,并对比了运算符的使用。此外,提到了冻结集合frozenset的不可变性和可哈希性的重要性,以及集合嵌套时需使用frozenset的技巧。
摘要由CSDN通过智能技术生成

1.创建集合

创建集合有三个方法:

  • 使用花括号,元素之间以逗号分隔:{“FishC”, “Python”}
  • 使用集合推导式:{s for s in “FishC”}
  • 使用类型构造器,也就是 set():set(“FishC”)

2.集合的随机性

>>> set("FishC")
{'i', 'C', 's', 'F', 'h'}

从这里我们不难发现,集合无序的特征,传进去的是 ‘F’、‘i’、‘s’、‘h’、‘C’,它这里显示的却是 ‘i’、‘C’、‘s’、‘F’、‘h’,在你们的电脑上结果还可能不一样,这就是随机性。

由于集合是无序的,所以我们不能使用下标索引的方式去访问它:

>>> s = set("FishC")
>>> s[0]
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    s[0]
TypeError: 'set' object is not subscriptable

不过我们可以使用 in 和 not in 来判断某个元素是否存在于集合中:

>>> 'C' in s
True
>>> 'c' not in s
True

3.访问集合

如果想要访问集合中的元素,可以使用迭代的方式:

>>> for each in s:
...     print(each)
...
F
h
i
s
C

4. 集合必杀技 —— 去重

集合另外一个特点就是唯一性,小甲鱼本鱼觉得,这也是集合最大的优势。比如利用集合,咱们就可以轻松地实现去重的操作:

>>> set([1, 1, 2, 3, 5])
{1, 2, 3, 5}

在实际开发中,我们经常需要去检测一个列表中是否存在相同的元素?

那么在没有学习过集合之前,我们很有可能需要通过迭代来统计每个元素出现的次数,从而判断是否唯一……

但是,现在,咱们只需要这么写:

>>> s = [1, 1, 2, 3, 5]
>>> len(s) == len(set(s))
False
>>> s = [1, 2, 3, 5]
>>> len(s) == len(set(s))
True

5. 集合的方法

(1)列表、元组、字符串、字典它们都有一个 copy() 方法,那么集合也不例外:

>>> t = s.copy()
>>> t
{'h', 's', 'i', 'F', 'C'}

如果我们要检测两个集合之间是否毫不相干,可以使用 isdisjoint(other) 方法:

>>> s.isdisjoint(set("Python"))
False
>>> s.isdisjoint(set("JAVA"))
True

那么这个参数它并不要求必须是集合类型,可以是任何一种可迭代对象:

>>> s.isdisjoint("Python")
False
>>> s.isdisjoint("JAVA")
True

下面也是一样的,传入的参数,都只要求是可迭代对象的类型即可。

如果我们要检测该集合是否为另一个集合的子集,可以使用 issubset(other) 方法:

>>> s.issubset("FishC.com.cn")
True

如果我们要检测该集合是否为另一个集合的超集,可以使用 issuperset(other) 方法(对于两个集合 A、B,如果集合 B 中任意一个元素都是集合 A 中的元素,我们就说这两个集合有包含关系,称集合 A 为集合 B 的超集):

>>> s.issuperset("Fish")
True

除了检测子集和超集,我们还可以计算当前集合和其它对象共同构造的并集、交集、差集以及对称差集。

并集,就是将集合与其它集合的元素合并在一起,组成一个新的集合:

>>> s.union({1, 2, 3})
{1, 2, 3, 'h', 's', 'i', 'F', 'C'}

交集,就是找到多个集合之间共同的那些元素

>>> s.intersection("Fish")
{'h', 's', 'i', 'F'}

差集,就是找出存在于该集合,但不存在于其它集合中的元素:

>>> s.difference("Fish")
{'C'}

同时,上面的这三个都是支持多个参数的:

>>> s.union({1, 2, 3}, "Python")
{1, 2, 3, 'y', 'h', 'n', 'i', 'P', 's', 'o', 't', 'C', 'F'}
>>> s.intersection("Php", "Python")
{'h'}
>>> s.difference("Php", "Python")
{'s', 'C', 'F', 'i'}

最后一个是求对称差集,就是排除掉 s 集合和 other 容器中共有的元素后,剩余的所有元素,这个只能支持一个参数:

>>> s.symmetric_difference("Python")
{'t', 'y', 'F', 's', 'P', 'C', 'n', 'o', 'i'}

好了,那么上面这 6 种常见的操作,Python 也提供了相应的运算符,可以直接进行运算。

检测子集可以使用小于等于号(<=):

>>> s <= set("FishC")
True

那么检测真子集我们可以使用小于号(<):

>>> s < set("FishC")
False
>>> s < set("FishC.com.cn")
True

那么反过来,使用大于号(>)和大于等于号(>=)就是检测真超集和超集:

>>> s > set("FishC")
False
>>> s >= set("FishC")
True

并集使用管道符(|):

>>> s | {1, 2, 3} | set("Python")
{1, 2, 3, 'y', 'h', 'n', 'i', 'P', 's', 'o', 't', 'C', 'F'}

交集使用 and 符号(&):

>>> s & set("Php") & set("Python")
{'h'}

差集使用减号(-):

>>> s - set("Php") - set("Python")
{'s', 'C', 'F', 'i'}

对称差集使用脱字符(^):

>>> s ^ set("Python")
{'t', 'y', 'F', 's', 'P', 'C', 'n', 'o', 'i'}

注意:使用运算符的话,符号两边都必须是集合类型的数据才可以,不然会报错。

>>> s <= "FishC"
Traceback (most recent call last):
  File "<pyshell#46>", line 1, in <module>
    s <= "FishC"
TypeError: '<=' not supported between instances of 'set' and 'str'
>>> s | [1, 2, 3]
Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    s | [1, 2, 3]
TypeError: unsupported operand type(s) for |: 'set' and 'list'

6.冻结的集合

Python 将集合细分为可变和不可变两种对象,前者是 set(),后者是 frozenset():

>>> t = frozenset("FishC")
>>> t
frozenset({'s', 'C', 'i', 'F', 'h'})

被冻结的集合(frozenset())是不支持修改的。

如果我们尝试修改它,那么可怕的事情就会发生:

>>> t.update([1, 1], "23")
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    t.update([1, 1], "23")
AttributeError: 'frozenset' object has no attribute 'update'

7.仅使用与set()对象的方法

update(*others) 方法使用 others 容器中的元素来更新集合:

>>> s = set("FishC")
>>> s
{'s', 'C', 'i', 'F', 'h'}
>>> s.update([1, 1], "23")
>>> s
{'s', 1, 'C', 'i', 'F', 'h', '3', '2'}

intersection_update(*others)、difference_update(*others) 和 symmetric_difference_update(other) 分别是使用前面讲过的交集、差集和对称差集的方式来更新集合:

>>> s.intersection_update("FishC")
>>> s
{'s', 'C', 'i', 'F', 'h'}
>>> s.difference_update("Php", "Python")
>>> s
{'s', 'C', 'i', 'F'}
>>> s.symmetric_difference_update("Python")
>>> s
{'s', 't', 'C', 'o', 'h', 'i', 'y', 'F', 'n', 'P'}

如果希望要单纯地往集合里添加数据,可以使用 add(elem) 方法:

>>> s.add("45")
>>> s
{'s', 't', 'C', 'o', 'h', 'i', 'y', 'F', '45', 'n', 'P'}

在集合中删除某个元素,可以使用 remove(elem) 或者 discard(elem) 方法:

>>> s.remove("瓦迈")
Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    s.remove("瓦迈")
KeyError: '瓦迈'
>>> s.discard("瓦迈")

删除还有一个 pop() 方法,用于随机从集合中弹出一个元素:

>>> s.pop()
's'
>>> s.pop()
't'
>>> s.pop()
'C'
>>> s
{'o', 'h', 'i', 'y', 'F', '45', 'n', 'P'}

最后,clear() 方法就是将集合清空:

>>> s.clear()
>>> s
set()

8.可哈希

想要正确地创建字典和集合,是有一个刚性需求的 —— 那就是字典的键,还有集合的元素,它们都必须是可哈希的。

如果一个对象是可哈希的,那么就要求它的哈希值必须在其整个程序的生命周期中都保持不变。

通过 hash() 函数,可以轻松获取一个对象的哈希值:

>>> hash(1)
1
>>> hash(1.0)
1
>>> hash(1.001)
2305843009213441

Python 中大多数不可变对象是可哈希的,而那些可变的容器则不哈希:

>>> hash("FishC")
2090433017907150752
>>> hash([1, 2, 3])
Traceback (most recent call last):
  File "<pyshell#36>", line 1, in <module>
    hash([1, 2, 3])
TypeError: unhashable type: 'list'

前面我们说了,只有可哈希的对象,才有资格作为字典的键,以及集合的元素:

>>> {"Python":520, "FishC":1314}
{'Python': 520, 'FishC': 1314}
>>> {"Python", "FishC", 520, 1314}
{520, 1314, 'Python', 'FishC'}

9.集合的嵌套

如果要实现一个嵌套的集合,可不可行?

>>> x = {1, 2, 3}
>>> y = {x, 4, 5}
Traceback (most recent call last):
  File "<pyshell#39>", line 1, in <module>
    y = {x, 4, 5}
TypeError: unhashable type: 'set'

这样写是不行的,因为集合它是一个可变的容器,而可变的容器则是不可哈希。

那我们非要将集合嵌套,还有没有办法?

有!

没错,使用 “冰山美人” frozenset() 对象:

>>> x = frozenset(x)
>>> y = {x, 4, 5}
>>> y
{frozenset({1, 2, 3}), 4, 5}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰深入学习计算机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值