Python difflib库对序列匹配器的奇怪行为

时间:2018-05-05 18:46:17

标签: python biopython difflib rosalind

我对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用于更长的字符串?

1 个答案:

答案 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

摆脱了这种行为,允许子串匹配而不受限制 我以为我把它留在这里,因为我浪费了几个小时来梳理我的代码以找到这个问题。