如何使用 difflib.SequenceMatcher 获得多个匹配项?

dal*_*ogm 5 python regex difflib

我正在使用 difflib 来识别较长序列中短字符串的所有匹配项。然而,当有多个匹配项时,difflib 似乎只返回一个:

> sm = difflib.SequenceMatcher(None, a='ACT', b='ACTGACT')
> sm.get_matching_blocks()
[Match(a=0, b=0, size=3), Match(a=3, b=7, size=0)]
Run Code Online (Sandbox Code Playgroud)

我期望的输出是:

[Match(a=0, b=0, size=3), Match(a=0, b=4, size=3), Match(a=3, b=7, size=0)]
Run Code Online (Sandbox Code Playgroud)

实际上,字符串ACTGACT 在位置0 和4 处包含两个ACT 匹配项,大小均为3(加上字符串末尾的另一个大小为0 的匹配项)。

如何获得多个匹配项?我期待 difflib 返回两个位置。

fnl*_*fnl 2

正如 Jerry 指出的那样,并且 k-nut 正确回答了,您在解决问题时使用了错误的算法。老实说,k-nut 的答案并没有那么糟糕,但这并不是解决此类问题的最有效方法。我是一名生物信息学家,考虑到你的问题和示例,你似乎正在尝试解决“我们的”经典 DNA 序列比对/搜索问题(请参阅科学文献Altschul 或“Gene”Myers 等科学超级明星的科学如果您对实质细节感兴趣并想阅读有史以来被引用最多的论文之一)。

在长片段数据库中有效地查找短片段正是 Altschul 现在著名的BLAST算法启发式解决的问题和/或可以使用Smith-Waterman进行精确查找来完成。在 Python 中执行此操作的最有效方法可能是使用BioPython,特别是,您可能需要查看描述如何设置本地 NCBI BLAST+ 实例的部分。如果您还没有与 Python“结婚”,那么今天还有更快的 BLAST 实现,例如FSA-BLAST

另一方面,如果您需要精确匹配(与 BLAST 进行的启发式相反),如果您不介意长查询时间并且有一个小的参考序列(B在您的示例中),则可能会出现这种情况,您可以与官方史密斯-沃特曼 (SW) 对齐。如果没有,并且您仍然需要精确匹配,请首先使用 BLAST 过滤匹配,然后使用候选者的 SW 对齐来减少您的集合。

可以用纯 Python 实现 SW,甚至只使用任何现有的纯 Python 实现,但我仅建议出于纯粹的教育目的使用该路径(例如,查看GitHub 上的swalign )。如果您仍然想要一个相当强大的基于 Python 的实现,请查看scikit-bio进行 SW 对齐,尽管 scikit-bio 仍处于 alpha 状态。但首先请阅读上面链接的SW WikiPedia 页面,根据您拥有的硬件,您可以使用CUDAC++中的 GPU 或至少 SIMD 优化的实现。如果您想要一个带有 Python 包装器的好版本,请查看SSWlib