将FASTA文件字符串转换为列表时的内存限制

时间:2014-12-18 13:39:54

标签: python string list python-2.7 fasta

我正在使用python 2.7 我正在使用包含现代人Y染色体DNA序列的fasta文件。实际上它是一个长约20000000字符的字符串,如ATCGACGATCACACG .... 我想将这个非常长的字符串转换为三元组字符串列表,例如这个字符串:

My_sequence_string= "ATGTACGTCATAG"

到此列表:

My_sequence_list= ["ATG","TAC","GTC","ATA"]

这是我的代码:

str_Reading_Frame1=open("Ychromosome.fa", "r").read()
list_Reading_Frame1=[]
def str_to_list(list, str):
    if len(str)>2:
        list.append(str[:3])
        str_to_list(list, str[3:])
str_to_list(list_Reading_Frame1, str_Reading_Frame1)

但我看到内存限制错误。我认为问题在于调用其中的函数,但我不知道如何优化我的代码。我不想导入模块,比如Biopython,我想自己动手(在你的帮助下:-))

3 个答案:

答案 0 :(得分:2)

我相信这一行

str_Reading_Frame1=open("Ychromosome.fa", "r").read()

是立即将大字符串读入记忆中的问题。而你所做的递归肯定对性能没有帮助。除了每个递归调用的堆栈帧之外,你还要将一个巨大的字符串切片N次,这应该是O(N ^ 2)性能。

如果你一次读取3个字节,只要列表适合内存,除了不使用列表之外,这是你能做的最多的事情,并且一次只能迭代3个字符。 / p>

with open('Ychromosome.fa') as f:
    while True:
        triad = f.read(3)
        if len(triad) != 3:
            break
        My_sequence_list.append(triad)


>>> My_sequence_list
['ATG', 'TAC', 'GTC', 'ATA']

答案 1 :(得分:2)

您可以轻松使用生成器函数来避免将所有内容加载到内存中。

def data(x):
    '''x if a file object and data returns an iterable giving blocs of 3 characters'''
    while True:
        d = x.read(3)
        if len(d) != 3:
            raise StopIteration
        yield d

with open("Ychromosome.fa", "r") as str_Reading_Frame1:
    for triad in data(str_Reading_Frame1):
        # use triad one at a time
        ...

答案 2 :(得分:1)

我问这个问题写了一个关于获得DNA链密码子使用的代码。 jamylak的答案帮助我改进了我的代码并编写了我想要的代码。我在这里完整地写下来,因为我觉得它可能对其他人有用。

Bases=["A", "T", "C", "G"] #4 bases of DNA strands
#Generating 64 different codons
codons=[]
def Possible_Codons(Bases):
    for i in Bases:
        for j in Bases:
            for y in Bases:
                ins= "%s%s%s" % (i, j, y)
                codons.append(ins)
Possible_Codons(Bases)

#Generating 6 different reading frames
Code_file=open("3.fa", "r").read()
open("str_Reading_File1.fa", "w").write(Code_file)
open("str_Reading_File2.fa", "w").write(Code_file[1:])
open("str_Reading_File3.fa", "w").write(Code_file[2:])
open("str_Reading_File4.fa", "w").write(Code_file[::-1])
open("str_Reading_File5.fa", "w").write(Code_file[-2::-1])
open("str_Reading_File6.fa", "w").write(Code_file[-3::-1])
My_sequence_list=[]
numbers=["1", "2", "3", "4", "5", "6"] #It is used for calling files
for i in numbers:
    with open("str_Reading_File"+i+".fa") as f:
        while True:
            triad = f.read(3)
            if len(triad) != 3:
                break
            My_sequence_list.append(triad)
    print "In the reading frame "+i+", codon usage is:"
    for i in codons:
        print "%s = %s times" % (i, My_sequence_list.count(i))
    My_sequence_list=[]
    print "*****************\n"