如何与列表和集合相交以保留列表的顺序? 简单的例子:
k=[1,2,3,4]
d={3,2}
d.intersection(k)
[2,3]#this is the ideal result
编辑:速度是这里最重要的因素
答案 0 :(得分:6)
您必须使用列表理解,这样可以通过过滤来保持订单:
[i for i in k if i in d]
演示:
>>> k = [1, 2, 3, 4]
>>> d = {2, 3}
>>> [i for i in k if i in d]
[2, 3]
对于Python 3,这是最快的选择;你可以使用list(filter(d.__contains__, l))
,但这个简单的小例子比较慢:
>>> from timeit import timeit
>>> def listcomp(k, d):
... return [i for i in k if i in d]
...
>>> def filtered(k, d):
... return list(filter(d.__contains__, k))
...
>>> timeit('listcomp(k, d)', 'from __main__ import listcomp, k, d')
0.49590064199946937
>>> timeit('filtered(k, d)', 'from __main__ import filtered, k, d')
0.6533352420010488
当数据集大小增加时,时间会变得更糟:
>>> import random
>>> k = sorted([random.randrange(1000) for _ in range(1000)])
>>> d = {random.randrange(1000) for _ in range(100)}
>>> timeit('listcomp(k, d)', 'from __main__ import listcomp, k, d', number=10000)
0.30027976899873465
>>> timeit('filtered(k, d)', 'from __main__ import filtered, k, d', number=10000)
0.4524774450001132
在Python 2中,filter()
是更快的选择,给定足够大的输入:
>>> from timeit import timeit
>>> import random
>>> def listcomp(k, d):
... return [i for i in k if i in d]
...
>>> def filtered(k, d):
... return filter(d.__contains__, k)
...
>>> k = [1, 2, 3, 4]
>>> d = {2, 3}
>>> timeit('listcomp(k, d)', 'from __main__ import listcomp, k, d')
0.4015800952911377
>>> timeit('filtered(k, d)', 'from __main__ import filtered, k, d')
0.4407978057861328
>>> k = sorted([random.randrange(1000) for _ in range(1000)])
>>> d = {random.randrange(1000) for _ in range(100)}
>>> timeit('listcomp(k, d)', 'from __main__ import listcomp, k, d', number=10000)
0.4594550132751465
>>> timeit('filtered(k, d)', 'from __main__ import filtered, k, d', number=10000)
0.28088998794555664
我不知道有任何更快的选择; available ordered set implementations都是Pure-python解决方案,而且速度较慢。