Python 将文件字符串转换为列表时的内存限制
我正在使用python 2.7 我正在处理一个包含现代人类Y染色体DNA序列的fasta文件。实际上,它是一个大约20000000个字符的长字符串,就像ATCGACGATCACG。。。。 我想将这个很长的字符串转换为一个三元组字符串列表,例如这个字符串: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("
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这是我答案的扩展,它避免了将整个列表存储在内存中。这取决于你是否需要把它存储在内存中,如果你不需要,那么就使用它真的谢谢你。你节省了我的时间。