从列表中的元素增加string时循环失败

我有序列发生器的一些问题。 我有一个文件,每行包含一个片段(8个字母)。 我从文件加载到列表中,其中每个元素是一个片段。 这是DNA,所以它应该这样:

1.采取第一个8个字母的元素
2.检查前7个字母与前7个字母相同的元素。
3.从第二个元素中添加第八个字母到顺序。

它应该是这样的:

ATTGCCAT TTGCCATA TGCAATAC 

所以序列:ATTGCCATAC

不幸的是,它只添加一个元素。 :(第一个元素是给出的(我们知道它),我这样做是第一个文件(第一行)。

这里是代码:

 from os import sys import random def frag_get(seqfile): frags = [] f_in = open(seqfile, "r") for i in f_in.readlines(): frags.append(i.strip()) f_in.close() return frags def frag_list_shuffle(frags): random.shuffle(frags) return frags def seq_build(first, frags): seq = first for f in frags: if seq[-7:] == f[:7]: seq += f[-1:] return seq def errors(): pass if __name__ == "__main__": frags = frag_get(sys.argv[1]) first = frags[0] frags.remove(first) frags = frag_list_shuffle(frags) seq = seq_build(first, frags) check(sys.argv[2], seq) spectrum(sys.argv[2], sys.argv[3]) 

我已经删除了检查和频谱function,因为它是简单的计算,如长度比较,所以它不是什么原因导致我想的问题。

我将非常感谢您的帮助!

问候,Mateusz

由于你的碎片被混洗,你的算法需要考虑到这一点。 目前,你只是循环一次片段,如果它们没有按照正确的顺序,那么不可能包含多个片段。 例如,假设您有5个片段,我将按照您的顺序依次引用它们。 现在这些碎片有点不合适:

1 – 3 – 2 – 4 – 5

你的算法将从1开始,跳过3,然后匹配2,在末尾添加一个基数。 然后它会检查4和5,然后完成,从未到达片段3。

你可以很容易的解决这个问题,每次你添加一个base时,再次启动你的循环,但是,这将会非常严重的扩展到大量的基础。 相反,我建议将你的片段加载到一个trie中 ,然后在每次添加一个base时搜索下一个片段,直到你为每个片段添加了一个base或者你不能再找到匹配的片段。

为我工作:

 >>> seq = "ATTGCCAT" >>> frags = ["TTGCCATA", "TGCCATAC"] >>> for f in frags: ... if seq[-7:] == f[:7]: ... seq += f[-1:] ... >>> seq 'ATTGCCATAC' 

你的例子中有一个拼写错误,TGCAATAC应该是TGCCATAC。 但修复它的工作。

为了好玩和兴趣,我用OO重写了这个问题。 看看你的想法:

 import collections import sys import random usage = """ Usage: sequence fname expected Where fname: name of file containing fragments expected: result-string which should be obtained by chaining from first fragment. """ class Frag(str): MATCHLEN = 7 def __new__(cls, s=''): return str.__new__(cls, s.strip()) def head(self): return Frag(self[:Frag.MATCHLEN]) def tail(self): return Frag(self[Frag.MATCHLEN:]) def nexthead(self): return Frag(self[-Frag.MATCHLEN:]) def check(self, s): return self.__eq__(s) def __add__(self, s): return Frag(str(self).__add__(s)) class Fraglist(list): @classmethod def fromFile(cls, fname): with open(fname, "r") as inf: lst = [Frag(ln) for ln in inf] return cls(lst) def shuffle(self): random.shuffle(self) class Sequencer(object): def __init__(self, seq=None): super(Sequencer, self).__init__() self.sequences = collections.defaultdict(list) if seq is not None: for frag in seq: self.sequences[frag.head()].append(frag.tail()) def build(self, frag): res = [frag] match = frag.nexthead() while match in self.sequences: next = random.choice(self.sequences[match]) res.append(next) match = (match + next).nexthead() return Frag(''.join(res)) def main(): if len(sys.argv) != 3: print usage sys.exit(-1) else: fname = sys.argv[1] expected = sys.argv[2] frags = Fraglist.fromFile(fname) frag1 = frags.pop(0) frags.shuffle() seq = Sequencer(frags) result = seq.build(frag1) if result.check(expected): print "Match!" else: print "No match" if __name__=="__main__": main()