家庭作业协助
我需要编写一个能够从用户那里获取含有DNA密码子的字符串的函数,例如
'ACATTTGCTTCTGACACAACTGTGTTCACTAGCAACCTCAAAC'
将字符串分成3个组,然后将每个组与字典项匹配。但程序必须只打印出键,而不是值。
输入:ATTGHIATGTTTTTCTYU
分离:[ATT] [GHI] [ATG] [TTT] [TTC] [TYU]
输出:IMFF
这是我到目前为止所拥有的
dna_codons = {'I': 'ATT' 'ATC' 'ATA',
'L': 'CTT' 'CTC' 'CTA' 'CTG' 'TTA' 'TTG',
'V': 'GTT' 'GTC' 'GTA' 'GTG',
'F': 'TTT' 'TTC',
'M': 'ATG',
}
def translate(sequence):
n = 3
MyList = [sequence[i:i+n] for i in range(0, len(sequence), n)]
for codon in MyList:
for slc in dna_codons.keys():
if codon == slc:
print slc
print translate(raw_input('type in DNA sequence: '))
答案 0 :(得分:2)
使用列表推导和生成器将输入字符串拆分为块,可以更轻松地实现目标。
尝试这样的事情:
in_seq = 'ATTGHIATGTTTTTCTYU' # change this to input()
_codes = { # your original dict is incorrect
'ATT': 'I', 'ATC': 'I', 'ATA': 'I',
'CTT': 'L', 'CTC': 'L', 'CTA': 'L', 'CTG': 'L', 'TTA': 'L', 'TTG': 'L',
'GTT': 'V', 'GTC': 'V', 'GTA': 'V', 'GTG': 'V',
'TTT': 'F', 'TTC': 'F',
'ATG': 'M',
}
def split_seq(s, n=2):
""" split string to chunks of size n """
i = 0
while i < len(s):
yield s[i:i + n]
i += n
out_codes = [_codes[z.upper()] for z in split_seq(in_seq, 3) if z.upper() in _codes]
result = ''.join(out_codes)
print(result)
输出:
IMFF
如果要查看单独的列表,请键入print(list(split_seq(in_seq, 3)))
:
['ATT', 'GHI', 'ATG', 'TTT', 'TTC', 'TYU']
如果您不想使用发电机,请将其替换为普通功能:
def split_seq(s, n=2):
res = []
i = 0
while i < len(s):
res.append(s[i:i + n])
i += n
return res
答案 1 :(得分:0)
您的代码的主要问题是'I': 'ATT' 'ATC' 'ATA',
无法正常工作。字符串只是连在一起(ATTATCATA
)。您需要将这些字符串转换为列表:'I': ['ATT', 'ATC', 'ATA'],
。然后,您可以使用嵌套循环迭代字典和列表:
for slc in dna_codons.keys():
for item in dna_codons[slc]:
if codon == item:
print slc
最后,最后的print语句将始终打印none
,因为您的函数不会返回任何要打印的内容。理想情况下,您的函数应返回所需的输出,而不是将其打印为副作用:
aa_seq =''
for codon in MyList:
for slc in dna_codons.keys():
for item in dna_codons[slc]:
if codon == item:
aa_seq += slc
return aa_seq
当然,如果你必须循环遍历每个密码子的所有值,你就不会从使用字典中获得太多好处。使密码子成为键和氨基酸值会更有效率。这样你就可以使用:
aa_seq = ''
for codon in MyList:
aa_seq += dna_codons[codon]
return aa_seq
答案 2 :(得分:0)
首先,您必须更改dna_codons
以将值作为列表或元组。目前,三元组的字符串将被连接成一个字符串。
dna_codons = {
'I': ['ATT', 'ATC', 'ATA'],
'L': ['CTT', 'CTC', 'CTA', 'CTG', 'TTA', 'TTG'],
'V': ['GTT', 'GTC', 'GTA', 'GTG'],
'F': ['TTT', 'TTC'],
'M': ['ATG'],
}
现在你可以使用@ heathobrien的嵌套循环,但这些循环效率很低。我认为你应该改变字典,以便它从密码子映射到氨基酸。你可以用:
def transpose(d):
out = {}
for key, values in d.items():
for val in values:
out[val] = key
return out
codon_to_aa = transpose(dna_codons)
这会生成字典{'ATG': 'M', 'ATT': 'I', 'ATC': 'I', ...}
。
在那之后,剩下的就是直截了当。您只需要拆分序列并找到合适的映射。重用您的代码:
def translate(sequence):
n = 3
codons = (sequence[i:i+n] for i in range(0, len(sequence), n))
for codon in codons:
print codon_to_aa.get(codon, ''),
print
translate(raw_input('type in DNA sequence: '))
第一个print
后面的逗号确保下一个字符在同一行打印出来。空print
将结束该行。但是,我建议你将输出聚合成一个变量并立即打印出来。
可替换地:
def translate(sequence):
n = 3
return ''.join(codon_to_aa.get(codon, '') for codon in
(sequence[i:i + n] for i in xrange(0, len(sequence), n)))
print translate(raw_input('type in DNA sequence: '))
答案 3 :(得分:0)
这是使用itertools
配方为名为grouper()
的生成器函数执行此操作的方法。
from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# s -> (s0,s1,...sn-1), (sn,sn+1,...s2n-1), (s2n,s2n+1,...s3n-1), ...
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
DNA_CODONS = {
'ATT': 'I', 'ATC': 'I', 'ATA': 'I',
'CTT': 'L', 'CTC': 'L', 'CTA': 'L', 'CTG': 'L', 'TTA': 'L', 'TTG': 'L',
'GTT': 'V', 'GTC': 'V', 'GTA': 'V', 'GTG': 'V',
'TTT': 'F', 'TTC': 'F',
'ATG': 'M',
}
def translate(sequence, n=3):
return [codeon for codeon in (''.join(nt) for nt in grouper(sequence, n, ' ')
if codeon in DNA_CODONS)]
input_sequence = 'ACATTTGCTTCTGACACAACTGTGTTCACTAGCAACCTCAAAC'
print(translate(input_sequence)) # -> [['TTT'], ['GTG'], ['TTC'], ['CTC']]