【问题标题】:Python: Intersection of full string from list with partial stringPython:列表中的完整字符串与部分字符串的交集
【发布时间】:2013-01-17 22:07:42
【问题描述】:

假设我有一个字符串和一个字符串列表:

a = 'ABCDEFG'

b = ['ABC', 'QRS', 'AHQ']

如何提取列表 b 中与字符串 a 的一部分完全匹配的字符串?所以会返回类似于['ABC']

最重要的问题是我有几千万的字符串,所以时间效率是必不可少的。

【问题讨论】:

  • 您只想要第一个匹配项还是所有匹配项的列表?
  • 仅仅因为你有数千万个字符串并不意味着明显的答案太慢了。不要只是假设它很慢——计时然后看看。向我们展示代码,告诉我们需要多长时间,并告诉我们这太长了,否则人们会继续发布答案,告诉您您已经知道的内容。
  • 这将是一个控制台应用程序吗?或者您是否有要在其上运行此代码的服务器?
  • 如果您确实需要对此进行优化:b 是一个大字符串列表,您只需要针对单个 a 运行一次吗? (换句话说,预处理a 是不是显而易见的正确做法?)
  • 我有 50,000,000 个字符串和一个 6000 个字符串长的字符串列表。

标签: python list intersection


【解决方案1】:

如果你只想要 b 中的第一个匹配项:

next((s for s in b if s in a), None)

这具有在找到匹配项后立即短路的优点,而其他列表解决方案将继续运行。如果没有找到匹配,它将返回None

【讨论】:

  • 非常好的快速解决方案。我不确定它是 Pythonic(嘿,None 之前没有空格!);)
  • @mglison: 如果你想在上面的例子中重复匹配列表怎么样..ABCABCDEFG
【解决方案2】:

请记住,Python 的子字符串搜索 x in a 已经针对一般情况进行了很好的优化(并且用 C 编码,用于 CPython),因此一般情况下您不太可能击败它,尤其是使用纯 Python 代码。

但是,如果您有更专业的案例,您可以做得更好。

例如,如果您有一个包含数百万个字符串 b 的任意列表,所有这些字符串都需要在一个永远不会改变的巨大静态字符串 a 中进行搜索,那么预处理 a 可以使 巨大 区别。 (请注意,这与通常情况相反,其中预处理 patterns 是关键。)

另一方面,如果您预计匹配的可能性不大,并且您已经提前获得了整个b 列表,那么您可以通过以某种方式组织b 来获得一些巨大的收益。例如,如果"ABC" 已经失败,则搜索"ABCD" 是没有意义的;如果您需要同时搜索"ABC""ABD",您可以先搜索"AB",然后检查它后面是"C" 还是"D",这样您就不必重复自己了;等等(甚至可以将所有 b 合并到一个足够接近最优值的单个正则表达式中……尽管有数百万个元素,这可能不是答案。)

但是很难提前猜测,没有比您提供给我们更多的信息,您到底想要什么算法。

Wikipedia 对字符串搜索算法有很好的高级概述。还有一个website 专门用于一般的模式匹配,这似乎有点过时了,但我怀疑你是否会需要一个过去 3 年发明的算法。

【讨论】:

    【解决方案3】:

    答案:

    (x for x in b if x in a )
    

    这将返回一个生成器,该生成器将是匹配的列表。取第一个或循环它。

    【讨论】:

    • 如果他想要更多,他需要告诉我们他是如何运行它的,我也想知道他将如何将数以千万计的字符串加载到一个数组中。
    • @Nix:他确实明确说过“最重要的问题是我有几千万个字符串,所以时间效率很重要。”
    • @Nix:搜索x in a 的时间比迭代每个x 的时间要高几个数量级。而且我不明白如何指出你完全忽略了 OP 所谓的“最重要的问题”算作拖钓。
    • 那不是真的。 B是固定长度,A是可变长度。所以最坏的情况是我们谈论的是 0N 和 0MN。
    • @Nix:我什至不确定你在这里争论什么。你完全正确,做x for x in b for x in a的时间是O(AB);做x for x in b 的时间是O(B) 这意味着“迭代列表的时间”不是这里的问题。除非你说“二次并不比线性差”,或者“我知道 A
    【解决方案4】:
    In [3]: [s for s in b if s in a]
    Out[3]: ['ABC']
    

    在我的机器上,当b 包含 20,000,000 个元素时,这大约需要 3 秒(使用 ab 测试,其中包含与问题中的字符串相似的字符串)。

    【讨论】:

      【解决方案5】:

      您可能想看看以下算法:

      Boyer–Moore string search algorithm 还有wikipedia

      但如果不知道更多,这可能是矫枉过正!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-29
        • 1970-01-01
        • 1970-01-01
        • 2018-11-29
        • 2015-09-06
        • 2018-07-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多