我对difflib
库中的一个奇怪行为感到有些困惑。我尝试在字符串中找到重叠序列(实际上是来自Rosalind任务的Fasta序列)以将它们粘合在一起。代码adapted from here适用于较小的字符串长度(为了清楚起见,我在这里构造了一个来自公共子字符串a
的示例):
import difflib
def glue(seq1, seq2):
s = difflib.SequenceMatcher(None, seq1, seq2)
start1, start2, overlap = s.find_longest_match(0, len(seq1), 0, len(seq2))
if start1 + overlap == len(seq1) and start2 == 0:
return seq1 + seq2[overlap:]
#no overlap found, return -1
return -1
a = "ABCDEFG"
s1 = "XXX" + a
s2 = a + "YYY"
print(glue(s1, s2))
输出
XXXABCDEFGYYY
但是当字符串较长时,difflib
不再找到匹配项。
a = "AGGTGTGCCTGTGTCTATACATCGTACGCGGGAAGGTCCAAGTTAACATGGGGTACTGTAATGCACACGTACGCGGGAAGGTCCAAGTTAACTACGAAACGCGAGCCCATCTTTGCCGGTGTTAACTTGCTGTCAGGTGTTTGGCAAGGATCTTTGTTTGCCGGTGTTAACTTGCTGTCAGGTGTTTGGCCGGTGTTAACTTGCTGTCAGATGCGCGCCACGGCCAAATTCTAGGCACGCCAAATTCTAGGCACTTTAAGTGGTTCGATGATCCACGATGGTAAGCCAGCCGTACTTGC"
s1 = "XXX" + a
s2 = a + "YYY"
print(glue(s1, s2))
输出
-1
为什么会发生这种情况?如何将difflib
用于更长的字符串?
答案 0 :(得分:0)
我注意到这种行为开始了,当" ATCG"字符串超过200.在difflib
文档页面上查找此数字让我看到了这段话:
自动垃圾启发式:SequenceMatcher支持启发式 自动将某些序列项视为垃圾。启发式 计算每个项目在序列中出现的次数。如果 项目的重复项(在第一项之后)占帐户的1%以上 序列和序列至少有200个项目,这个项目是 标记为“流行”并被视为序列目的的垃圾 匹配。可以通过设置autojunk来关闭此启发式扫描 创建SequenceMatcher时参数为False。
由于序列只包含ATCG
,因此它们当然超过200个字符序列的1%,因此被认为是垃圾。将代码更改为
import difflib
def glue(seq1, seq2):
s = difflib.SequenceMatcher(None, seq1, seq2, autojunk = False)
start1, start2, overlap = s.find_longest_match(0, len(seq1), 0, len(seq2))
if start1 + overlap == len(seq1) and start2 == 0:
return seq1 + seq2[overlap:]
return -1
摆脱了这种行为,允许子串匹配而不受限制 我以为我把它留在这里,因为我浪费了几个小时来梳理我的代码以找到这个问题。