列表搜索中的快速字符串

时间:2011-12-18 04:21:16

标签: python string performance list

使用Python 3,我有一个包含超过100,000个字符串(list1)的列表,每个字符最多300个字符。我还有一个超过900万个子串的列表(list2) - 我想计算list2中子串的元素数量。例如,

list1 = ['cat', 'caa', 'doa', 'oat']
list2 = ['at', 'ca', 'do']

我希望函数返回(映射到list2):

[2, 2, 1]

通常情况下,这很简单,只需要很少。但是,由于列表的大小,我有效率问题。我想找到返回该计数器列表的最快方法。

我已经尝试了列表推导,生成器,地图,各种循环,我还没有找到一种快速的方法来完成这项简单的任务。什么是理论上最快的方法来完成这个目标,最好快速采取O(len(list2))步骤?

3 个答案:

答案 0 :(得分:2)

设置M = len(list1)N = len(list2)

对于list2中的每个N个条目,您将不得不对list1中的条目进行M比较。这是O(M x N)最糟糕的运行时间。如果您进一步了解,我们可以将list2中的每个条目的长度设置为1,list1中的每个条目的长度为300,然后您的运行时间为O(300M x N)。< / p>

如果性能确实存在问题,请尝试动态编程。这是一个开始:

1)按照长度的升序排序list2,如下所示:

['scorch', 'scorching', 'dump', 'dumpster', 'dumpsters']

2)将它们分类到子列表中,使得每个前面的条目都是前进条目的子集,如下所示:

[['scorch', 'scorching'] , ['dump', 'dumpster', 'dumpsters']]

3)现在,如果您与list1进行比较并且'scorch'不在那里,那么您也不必搜索'scorching'。同样,如果'dump'不在,'dumpster''dumpsters'

注意最差情况下的运行时间仍然相同

答案 1 :(得分:1)

我相信这个任务可以使用Aho Corasick string matching机器在线性时间内解决。 请参阅this回答以获取更多信息(也许您可以从该问题的其他答案中获得想法 - 这几乎是相同的任务,我认为Aho Corasick是理论上最快的解决方法这一点)。

您必须以这种方式修改字符串匹配机器,而不是返回匹配,它会将每个匹配的子字符串的计数器增加一。 (这应该只是一个小修改)。

答案 2 :(得分:0)

不确定如何避免使用某种O(n ** 2)算法。这是一个简单的实现。

>>> def some_sort_of_count(list1, list2):
>>>     return [sum(x in y for y in list1) for x in list2]
>>> 
>>> list1 = ['cat', 'caa', 'doa', 'oat']
>>> list2 = ['at', 'ca', 'do']
>>> some_sort_of_count(list1, list2)
[2, 2, 1]