【问题标题】:Most efficient way to check if any substrings in list are in another list of strings检查列表中的任何子字符串是否在另一个字符串列表中的最有效方法
【发布时间】:2015-02-03 17:16:53
【问题描述】:

我有两个列表,一个是单词,另一个是字符组合。仅返回与列表中任何内容都不匹配的组合的最快方法是什么?

我已尝试使其尽可能精简,但是当它使用 3 个字符进行组合时仍然很慢(4 个字符最多需要 290 秒,甚至不会尝试 5 个)

这是一些示例代码,目前我正在将所有单词转换为一个列表,然后在字符串中搜索每个列表值。

#Sample of stuff
allCombinations = ["a","aa","ab","ac","ad"]
allWords = ["testing", "accurate" ]

#Do the calculations
allWordsJoined = ",".join( allWords )
invalidCombinations = set( i for i in allCombinations if i not in allWordsJoined )

print invalidCombinations
#Result: set(['aa', 'ab', 'ad'])

我只是好奇是否有更好的方法来使用集合来做到这一点?用 3 个字母的组合,有 18278 个要搜索的列表项,对于 4 个字母,最多可以搜索到 475254 个,所以目前我的方法还不够快,尤其是当单词列表字符串大约 100 万个字符时。

Set.intersection 如果您需要整个字符串,这似乎是一个非常有用的方法,所以肯定有类似的东西来搜索子字符串。

【问题讨论】:

    标签: python set


    【解决方案1】:

    首先想到的是,您可以通过检查当前组合与已经“无效”的组合来优化查找。 IE。如果 ab 无效,那么 ab.? 也将无效,没有必要检查。

    还有一件事:尝试使用

    for i in allCombinations:
        if i not in allWordsJoined:
            invalidCombinations.add(i)
    

    而不是

    invalidCombinations = set(i for i in allCombinations if i not in allWordsJoined)
    

    我不确定,但较少的内存分配对于实际数据运行来说可能是一个小小的提升。

    【讨论】:

    • 为什么你认为内存分配较少?
    • 啊,感谢您的想法,但速度仍然非常相似,使用 3 级组合时,两者的结果都在 7.3-7.8 秒左右。至于你的第一点,我考虑过这一点,但添加代码来停止此类检查可能会比它加快速度更慢,而且在我的单行方式中工作有点困难:P
    • 彼得,我不会添加支票。我会研究不同的数据结构,以消除检查的需要。
    【解决方案2】:

    查看一个集合是否包含一个项目是 O(1)。您仍然需要遍历您的组合列表(有一些例外。如果您的单词没有“a”,则不会有任何其他包含“a”的组合。您可以使用一些类似树的数据结构this) 与您的原始单词集进行比较。

    您不应该将您的单词表转换为字符串,而应该将其转换为集合。你应该得到 O(N) 其中 N 是你的组合的长度。

    另外,我喜欢 Python,但它不是最快的语言。如果这是您需要做的唯一任务,并且它需要非常快,并且您无法改进算法,那么您可能需要查看其他语言。您应该能够非常轻松地制作原型,以了解不同语言的速度差异。

    【讨论】:

    • 谢谢,我不确定如何将它作为一个集合进行迭代。我试过set( i for i in allCombinations if i in set( k for k in allWords) ),如果这就是你的意思,但几分钟后它仍在执行,这比其他方法的 7 秒慢得多。
    • Try: > set(allwords) 我仍然强烈建议你为你的 allCombinations 使用一些不同的数据结构。二进制搜索是 O(log N),真的很棒!
    • 对不起,你的建议比我目前的 python 知识高级一点哈哈,你的意思是像allCombinations["a"]["a"]["b"] = None 那样做,它会递归地向内搜索直到匹配没找到?这是我目前列出的代码 - pastebin.com/cN6mjNiQ
    • 肯定更复杂!我会先尝试另一种语言。在 Go 中创建原型(甚至尝试 pypy!)
    • 啊,好的,谢谢,公平地说,这更多是我正在研究的个人想法,所以我挤出每一个可能的速度并不重要,我只是想变得更先进使用 Python,因为它是 Maya 支持的语言 :)
    猜你喜欢
    • 1970-01-01
    • 2018-06-06
    • 1970-01-01
    • 2020-08-09
    • 2017-04-27
    • 2012-11-23
    • 2013-04-29
    • 1970-01-01
    • 2019-10-03
    相关资源
    最近更新 更多