我正在使用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,我想自己动手(在你的帮助下:-))
答案 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"