Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将文件字符串转换为列表时的内存限制_Python_String_List_Python 2.7_Fasta - Fatal编程技术网

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

Python 将文件字符串转换为列表时的内存限制,python,string,list,python-2.7,fasta,Python,String,List,Python 2.7,Fasta,我正在使用python 2.7 我正在处理一个包含现代人类Y染色体DNA序列的fasta文件。实际上,它是一个大约20000000个字符的长字符串,就像ATCGACGATCACG。。。。 我想将这个很长的字符串转换为一个三元组字符串列表,例如这个字符串: My_sequence_string= "ATGTACGTCATAG" 在此列表中: My_sequence_list= ["ATG","TAC","GTC","ATA"] 这是我的代码: str_Reading_Frame1=open("

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

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这样的模块,我想自己做(在你的帮助下:-)

我相信这句话

str_Reading_Frame1=open("Ychromosome.fa", "r").read()
一次将一个巨大的字符串读入Memory是个问题。而且你正在做的递归对性能毫无帮助。以及每个递归调用的堆栈帧,您将一个巨大的字符串切分N次,这应该是O(N^2)性能

如果您一次读取3个字节,只要列表适合内存,这是您可以做的最多的事情,而不是不使用列表,一次只迭代3个字符,这也是建议的

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']

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

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
        ...

我问这个问题是为了写一个关于获取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"

看看这样的答案:你真的需要完整的清单吗?看来iterables对你更有用处。@jonrsharpe拥有三元组对我来说很重要,但它可能是列表以外的东西。我的意思是,你是否需要同时使用所有三元组?现在我正在阅读有关iterables的文章,谢谢你的回答,但我比你的答案更容易理解jamylak的答案。这比我目前掌握的python知识还要多。非常感谢。again@StackUnderFlow欢迎你。。。如果你可以在内存中加载一个完整的列表(对于最近的系统,你应该能够…),那么一定要使用jamylak的答案。这是一个更大的输入文件:-)@StackUnderFlow这是我答案的扩展,它避免了将整个列表存储在内存中。这取决于你是否需要把它存储在内存中,如果你不需要,那么就使用它真的谢谢你。你节省了我的时间。