Python中的高性能质量短字符串搜索

时间:2012-01-13 02:41:41

标签: python string search

问题:大型静态字符串列表提供为A,长字符串提供为BA中的字符串都非常短(关键字列表),我想检查A中的每个字符串是否都是B的子字符串并获取它们。

现在我使用一个简单的循环:

result = []
for word in A:
    if word in B:
        result.append(word)

但是当A包含~500,000或更多项目时,它会发生疯狂。

是否有适合此问题的库或算法?我尽力搜索但没有运气。

谢谢!

5 个答案:

答案 0 :(得分:14)

你的问题足够大,你可能需要用算法蝙蝠击中它。

查看Aho-Corasick算法。您的问题陈述是对该算法所解决的问题的解释。

另外,请查看Nicholas Lehuen的PyTST包的作品。

在相关的Stack Overflow消息中也有引用提及其他算法,如Rabin-Karp:Algorithm for linear pattern matching?

答案 1 :(得分:2)

根据长字符串的长度,可能值得这样做:

ls = 'my long string of stuff'
#Generate all possible substrings of ls, keeping only uniques
x = set([ls[p:y] for p in range(0, len(ls)+1) for y in range(p+1, len(ls)+1)])

result = []
for word in A:
    if word in x:
        result.append(word)

显然,如果你的长字符串非常非常长,那么这也会变得太慢,但对于几百个字符以下的任何字符串它应该更快。

答案 2 :(得分:1)

我不知道这是否会更快,但它更加pythonic:

result = [x for x in A if x in B]

答案 3 :(得分:1)

B的所有单词单词打包到一个新列表中,该列表由' '分割的原始字符串组成。然后,对于B中的每个元素,针对A的每个元素测试成员资格。如果您找到一个(或多个),请从A删除它们,并在A为空时立即退出。

如果没有选择退出设置,您的方法似乎会让500,000名候选人参与其中。

答案 4 :(得分:1)

假设您拥有相同长度的所有关键字(稍后您可以将此算法扩展为不同的长度)

我接下来可以建议:

  1. 预先计算每个关键字的一些哈希值(例如xor哈希):

    hash256 = reduce(int.__xor__, map(ord, keyword))
    
  2. 创建一个字典,其中key是一个哈希值,以及相应关键字的值列表

  3. 保存关键字长度

    curr_keyword = []
    for x in B:
      if len(curr_keyword) == keyword_length:
         hash256 = reduce(int.__xor__, map(ord, curr_keyword))
         if hash256 in dictionary_of_hashed:
            #search in list
    
      curr_keyword.append(x)
      curr_keyword = curr_keyword[1:]
    
  4. 像这样的东西

相关问题