python:从有序列表中对键的子列表进行排序的最快方法是什么

时间:2012-12-05 20:42:49

标签: python

我有一个关于从一长串密钥中排序无序的密钥子列表的速度的问题。所以

keys =['a','c','b','f','e','d','p','t','s','y','h']
sub_list = ['y','b','a','p']

我有两个想法:

sublist = sorted(sub_list, key=keys)

,或者

sublist = [key for key in keys if key in sub_list]

对于我所知道的一切,可能有比这两个更好的方法。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

只是时间:

In [3]: %timeit sorted(sub_list, lambda a,b: cmp(keys.index(a), keys.index(b)))
100000 loops, best of 3: 6.22 us per loop

In [4]: %timeit sublist = [key for key in keys if key in sub_list]
1000000 loops, best of 3: 1.91 us per loop

编辑(更多方法)

%timeit sorted(sub_list, key=keys.index)
100000 loops, best of 3: 2.8 us per loop

此示例使用宏(或ipython中调用的任何内容),但您可以自己使用timeit

import timeit

p = """
keys =['a','c','b','f','e','d','p','t','s','y','h']
sub_list = ['y','b','a','p']"""

s = "sorted(sub_list, lambda a,b: cmp(keys.index(a), keys.index(b)))"

timeit.Timer(stmt=s, setup=p).timeit()
>>> 8.40028386496742

s = "[key for key in keys if key in sub_list]"
timeit.Timer(stmt=s, setup=p).timeit()
>>> 1.9661344551401498

所以你可以尝试所有你能想到的方法并选择最快的

答案 1 :(得分:0)

为什么不只是sub_list.sort()?它可能不是最快的,但它当然很容易理解。

答案 2 :(得分:0)

我认为您应该使用sub_list.sort进行排序,因为.sort进行了一次就地排序,其中sorted在排序之前复制了子列表

你所做的列表理解非常慢,因为最后一个if语句必须扫描整个sub_list(因此每个键执行n次操作)

sublist = [key for key in keys if key in sub_list]

更快的列表理解是这个

sub_set = set(sublist)
sub_list = [key for key in keys if key in sub_set]

因为散列和集合查找是O(1),其中列表查找是O(n)

排序一般是O(nlog(n)) 列表理解是O(n)

然而假设通过:

sublist = sorted(sub_list, key=keys)
你的意思是:

sublist = sorted(sub_list, key=keys.index)

你有列表查找而不是哈希查找,因此你的排序从O(nlog(n))到O((n ** 2)* log(n))

要将排序返回到nlog(n),您必须将密钥列表转换为哈希,如下所示:

keys = dict(zip(keys, range(len(keys))))
sublist = sorted(sub_list, key=keys)