Python 分享一个去重

Karaser · 2019年05月28日 · 最后由 Karaser 回复于 2019年05月31日 · 3414 次阅读

废话不多说,直接来!

由于时间问题我也只是创建了一个 10W 长度的数组,但是效果应该可以被显而易见。

第一种:
in 关键字,其实 Python 是很推荐大家使用 in 关键字来检索包含这种关系的,在字符串中,list 中检索都很方便,但是如果用来去重,效率就很捉急了。

10W 数据用了一分钟,我要炸了。。。

其实还有很多种类似的手段,都是去直接操作 list 去重,这里就不一一例举了。

第二种:
itertools 分组的方式


这效率,谁说 Python 效率差来着

第三种:
其实还有一种是通过 set 的方式

效率也是非常非常高的,但是我展示以下方式是想表达
在实际编程中应该尽量少的操作 list,而去操作 dict 或者 set 这种数据结构,在效率上是质的改变


这种通过 dict 属性报错的特性能够很高效率的索引出来,这种方式在 JS 中也是适用的,只是 js 是以 undefined 的结果表达而不是 KeyError 的报错。
真的非常青睐 dict 这种数据结构了。
----------------------更新一波
修改了一下,更新了第三种的实现


速度竟然比 set 快,且不打乱原有顺序,看来之前还是想太多。。。

共收到 11 条回复 时间 点赞

去重为啥不直接转 tuple 啊

黑山老妖 回复

转元组?元组并没有不重复的特性呀。set 才有,set 效率也不错,但是会打乱顺序。

list 的 xxx in [list] 是 o(n) dict xxx in [dict] 是 O(1) set 最差 O(n)

主要还是背后的实现逻辑决定, dict 效率高是因为直接用了 hash(key) 寻址. O(1) 肯定快

Karaser 回复

是 set,记错了。基础不牢,见笑了~

mythmgn 回复

是的

只是觉得帖主的例子有点糙:

  1. 有些代码底层会做优化;
  2. 掺杂了 try expect的和没添加的对比 (但是可以认为负重跑比你快的人,去掉包袱也必然比你跑的快)

反正只会 py 不会底层的怎么讨论都是菜鸡,我承认我是不会下面的代码;所以终究做不好

hellohell 回复

1、不知道您想表达什么,底层代码优化是必然的,您写一个 print 其实也会优化,但是选择符合业务的数据结构就是能够明显的提高效率
2、不知道您仔细看了没有,KeyError 是 List 对象主动抛出来的一个错误,在无法索引到 key 的时候就会出现这个错误,他仅仅是一个逻辑的判断,你也可以使用 list.get() 去判断有没有这个值,在我的测试过程中 try catch 效率甚至还会高于 get,Python 给出这种捕获机制的语法糖就是允许你这么玩的。负重不存在的。
3、这段代码不知道您说的难度在哪里,但是明显是偏题了,这段代码只是在比较初始化 list 和 dict 的效率,和在 list、dict 中索引一个值是两码事,当然了,dict 需要书写一个散列的 hash 表初始化速度肯定慢过 list,但是优势就在于索引速度,所以我说要选择符合业务逻辑的数据结果呢~

我理解这个文要表达的意思 : in 的速度 (对列表操作) 比哈希中按键查效率差;
我属于过度解读.

list({_:None for _ in r})

 

我查了下 groupby 的思想,先排序后去重,是要快很多,但是分组有点浪费时间了,优化了下

def test(l):
    n = []
    l.sort()
    repeat = None
    for e in l:
        if e != repeat:
            repeat = e
            n.append(e)
    return n

然而速度还是比不上 set

a2021 回复

set 是挺好的,但是排序的方式会打乱顺序
我又修改了一下,速度比 set 还快,而且保留顺序
def dictWay2(l):
d = {}
for i in l:
d[i] = None
return list(d.keys())

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册