set集合判断集合中是否有无元素_你有真正把 Python Set 当作数学集合吗?

16194fac-6b13-eb11-8da9-e4434bdf6706.png

视频原文:Set Practice: learning from Python's set types - PyCon 2019,PPT在这,作者为《流畅的 Python》作者 LucianoRamalho

set是 Python 非常重要的一种数据结构,不能包含相同的元素,几乎所有用过 Python 的人都知道, set有进行列表去重的功能。

但是鲜有人意识到了 set 在数学概念上的意义,那就是集合,能进行交集、并集这些操作。很多时候使用 set把问题抽象成一个集合问题,能使问题既简单又高效。

来看一下不同语言对于 set的支持情况:Python、.Net、Ruby 都很好地支持了 set数据结构。

1a194fac-6b13-eb11-8da9-e4434bdf6706.png

0x00 Set 基础知识

set comprehension

22194fac-6b13-eb11-8da9-e4434bdf6706.png

25194fac-6b13-eb11-8da9-e4434bdf6706.png

in 查询

时间复杂度为 O(1),应该 set 内部使用的是 hash table,所以判断元素在不在集合里面速度非常快。 in操作在底层实际上调用的是 set__contains__方法。

早期的 Python 事实上也是没有 set 的,那时候用的是 dict 来模拟 set。

集合操作

python 内置了很多 operators,能让你像运算数学公式一样操作操作集合。

28194fac-6b13-eb11-8da9-e4434bdf6706.png

2b194fac-6b13-eb11-8da9-e4434bdf6706.png

2d194fac-6b13-eb11-8da9-e4434bdf6706.png
第20行是德摩根定律。

methods

上述的 operators 底层是 set 定义的很多实用方法,下图在《流畅的 Python》里面有:

30194fac-6b13-eb11-8da9-e4434bdf6706.png

32194fac-6b13-eb11-8da9-e4434bdf6706.png

35194fac-6b13-eb11-8da9-e4434bdf6706.png

非数学相关的方法:

37194fac-6b13-eb11-8da9-e4434bdf6706.png

ABC

collections.abc定义了 Set数据结构, setmutableset都实现了 Setinterface。

3a194fac-6b13-eb11-8da9-e4434bdf6706.png

0x01 Case 1

需求:查询所有满足这种需求的商品:商品的描述信息中保护 query 中出现过的所有单词。(display product if all words in the query appear in the product description.)

go 语言中是没有 set 这种数据结构的,判断语句如下: found flag 用来判断是不是要结束循环。嵌套循环很不优雅!

3b194fac-6b13-eb11-8da9-e4434bdf6706.png

事实上这是一个集合问题,假设商品的描述为集合 D,查询语句为集合 Q,问题就变成了判断是否满足 Q ⊂ D。

3d194fac-6b13-eb11-8da9-e4434bdf6706.png

0x02 Case 2

需求:标记所有 favorited 且不在购物车的商品。

事先让你写一个方法,你第一反应是和我一样,用循环来解决吗?比如这种:

chart_list = []
def filter_goods(goods_list):
    ret = []
    for goods in goods_list:
        if goods.favorited and goods not in charts_list:
            ret.append(goods)
    return ret

这其实可以有更优雅的方法,可以把这个问题抽象成一个数学集合问题,设所有标记为喜欢的商品为集合 F,在购物车的商品为集合 C,那么要求的就是 F 和 非C 的交集∩。

40194fac-6b13-eb11-8da9-e4434bdf6706.png

42194fac-6b13-eb11-8da9-e4434bdf6706.png

如果你像我一样真正热爱计算机科学,喜欢研究底层逻辑,欢迎关注我的微信公众号:

45194fac-6b13-eb11-8da9-e4434bdf6706.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值