Python:加快多个列表中的匹配

时间:2018-07-19 17:08:11

标签: python performance list tuples matching

我有四个这样的列表:

L = [ (1,2), (3,5), (6,10), (7,8) ]
M = [ (1,3), (8,9), (12,13) ]
N = [ (6,10), (3,4), (5,6), (10,11), (12,13) ]
T = [ (6,10) , (1,4) ]

我想检查L,M和N内T的每个元组的存在/不存在:

[[True, False, True], [False, False, False]]

以下方法有效,但是当T,L,M和N的大小增加时,效率低下。

[[ y in x for x in [L, M, N] ] for y in T ]

对于大型列表,最有效的方法是什么?

4 个答案:

答案 0 :(得分:6)

list时间中搜索与列表长度成正比。因此,对于长列表来说,它很高。有针对搜索而优化的特殊数据结构。 python中最简单的是set。它计算每个元素的哈希(因此元素必须是可哈希的,并且整数元组是可以的)。 然后,您执行相同的检查。所以您只需要添加

L = set(L)
M = set(M)
N = set(N)

作为副作用,您将丢失列表中元素的顺序。并且,如果有非唯一值,它们将合并为一个。

有关速度更新:

如果搜索的值刚开始,则list中的搜索时间可能会很高。但是如果不是这种情况,set应该快得多,因为搜索时间与log(len(data))成正比。 list最坏的情况是list中没有搜索到的项目,因此它将需要检查每个项目。在这种情况下,在{M {1}}中搜索1M list比在set中搜索速度慢200K(仅在python3中检查)

答案 1 :(得分:0)

您还可以考虑使用Numpy数组,而不是普通的python列表和元组。 看起来here 由于必须检查列表中的每个元素,因此总速度将始终呈线性比例,因此您必须使用更快的实现(例如numpy)或使用更快的语言(例如Rust,C,C ++)扩展代码。

使用np.asarray(listname)函数进行转换

答案 2 :(得分:0)

如果可以处理其他输出格式,则还可以设置交集。

>>> L = set([ (1,2), (3,5), (6,10), (7,8) ])
>>> M = set([ (1,3), (8,9), (12,13) ])
>>> N = set([ (6,10), (3,4), (5,6), (10,11), (12,13) ])
>>> T = set([ (6,10) , (1,4) ])
>>> [T & x for x in (L,M,N)]
[{(6, 10)}, set(), {(6, 10)}]

这将为您提供一组元组的列表,它们分别出现在两组中。这应该比使用嵌套循环更快。

答案 3 :(得分:-1)

使用字典并比较这些值。

LMNT = {'L':[(1,2),(3,5),(6,10),(7,8)],
'M':[(1,3),(8,9),(12,13)],
'N':[ (6,10), (3,4), (5,6), (10,11), (12,13) ],
'T':[ (6,10) , (1,4) ]}

然后您可以比较字典。 LMNT['M'][0][1]的值为2

OR

LMNT['N'][4]的值为(12,13)