我正在编写一个程序,我希望在for
循环中使用3个变量,并且每个变量都应该从不同的起始索引运行。这是我的代码中的一个片段。我有一个名为密码子的表格,其中我对每三个字母都有一些价值,例如'atg':'F'
,'ggg':'Q'
,'ttg':'E'
等
seq='atgggggggcccccc'
seqlen= len(seq)
aaseq1=[]
aaseq2=[]
aaseq3=[]
for i in range(0,seqlen,3):
codon1 = seq[i:i+3]
aa1 = codons[codon1]
aaseq1.append(aa1)
print ''.join(aaseq1)
在这段代码中,我从位置0运行变量i
,但我想再使用2个变量(j
和k
),它们分别从1和2运行并追加aaseq2
和aaseq3
列表中的结果。
codon2 = seq[j:j+3]
codon3 = seq[k:k+3]
答案 0 :(得分:2)
您似乎在寻找内置的zip
函数,它允许锁步迭代。结合元组解包,它的工作方式如下:
>>> for i,j in zip(range(3), range(10,13)):
... print(i,j)
...
0 10
1 11
2 12
zip
的参数是你通常可以在for
循环的那一部分中使用的任何参数,你可以拥有任意数量的参数(只要你分配给相同数量的变量,或者只有一个变量,它在每次迭代时都是一个元组。)
答案 1 :(得分:2)
(我通常)尽量不要在Python中使用循环。虽然(正如@ PM-2ring在评论中指出的那样)列表表达式不一定比显式循环更快,但有些人发现python可以处理迭代数据的细节,因此可以更快地编写,理解和调试尽可能。
下面是你的程序的一些版本,最终“pythonified”到四行,只是为了看看它去了哪里。
通常有一些方法可以让Python使用索引和列表表达式为您做事。这些可以是简洁而强大的东西,许多python函数只是做你想要的。例如,拉链只是在最后丢弃悬挂的基础对而没有抱怨。
打印陈述只是为了看看发生了什么,当然会在以后删除它们。
seq='atgggggggcccccc'
s1 = seq[0::3] # you can drop the zero, it's just for readability
s2 = seq[1::3]
s3 = seq[2::3]
c1 = zip( s1, s2, s3 )
c2 = zip( s2, s3, s1[1:] ) # frame shift of 1
c3 = zip( s3, s1[1:], s2[1:] ) # frame shift of 2
print c1
print c2
print c3
co1 = [bp1+bp2+bp3 for (bp1, bp2, bp3) in c1]
co2 = [bp1+bp2+bp3 for (bp1, bp2, bp3) in c2]
co3 = [bp1+bp2+bp3 for (bp1, bp2, bp3) in c3]
print co1
print co2
print co3
aaseq1 = [codons(thing) for thing in c1]
aaseq2 = [codons(thing) for thing in c2]
aaseq3 = [codons(thing) for thing in c3]
......也可以这样写:
s1, s2, s3 = [seq[i::3] for i in range(3)] # use list comprehension and unpacking
c1 = zip( s1, s2, s3 )
c2 = zip( s2, s3, s1[1:] ) # frame shift of 1
c3 = zip( s3, s1[1:], s2[1:] ) # frame shift of 2
co1, co2, co3 = [[tr[0]+tr[1]+tr[2] for tr in c] for c in [c1,c2,c3]]
aaseq1, asseq2, asseq3 = [[codons(trip) for trip in co] for co in [co1, co2, co3]]
这只是为了宣传更多的python。对于初学者来说,它可能不太可读。
这是进一步的pythonification(只是为了看看它在哪里......):
S = [seq[i::3] for i in range(3)] # three reading frames
C = zip(S[0], S[1], S[2]), zip(S[1], S[2], S[0][1:]), zip(S[2], S[0][1:], S[1][1:]) # group
CO = [[''.join(tr) for tr in c] for c in C] # tuples to triplet strings
AASEQs = [[codons(trip) for trip in co] for co in CO] # look up Amino Acids
最后,如果你想将三个AA序列改为三个长串:
final_AASEQs = [''.join(AASEQ) for AASEQ in AASEQs]
只是为了好玩,这里是字典codons
的样子(来自Wikipedia,注意A,T,G,C基础的大写。所以问题seq = 'ATGGGGGGGCCCCCC'
codons = {'CTT': 'Leu', 'ATG': 'Met', 'AAG': 'Lys', 'AAA': 'Lys', 'ATC': 'Ile',
'AAC': 'Asn', 'ATA': 'Ile', 'AGG': 'Arg', 'CCT': 'Pro', 'ACT': 'Thr',
'AGC': 'Ser', 'ACA': 'Thr', 'AGA': 'Arg', 'CAT': 'His', 'AAT': 'Asn',
'ATT': 'Ile', 'CTG': 'Leu', 'CTA': 'Leu', 'CTC': 'Leu', 'CAC': 'His',
'ACG': 'Thr', 'CAA': 'Gln', 'AGT': 'Ser', 'CAG': 'Gln', 'CCG': 'Pro',
'CCC': 'Pro', 'TAT': 'Tyr', 'GGT': 'Gly', 'TGT': 'Cys', 'CGA': 'Arg',
'CCA': 'Pro', 'CGC': 'Arg', 'GAT': 'Asp', 'CGG': 'Arg', 'TTT': 'Phe',
'TGC': 'Cys', 'GGG': 'Gly', 'TAG': 'STOP', 'GGA': 'Gly', 'TGG': 'Trp',
'GGC': 'Gly', 'TAC': 'Tyr', 'GAG': 'Glu', 'TCG': 'Ser', 'TTA': 'Leu',
'GAC': 'Asp', 'CGT': 'Arg', 'GAA': 'Glu', 'TCA': 'Ser', 'GCA': 'Ala',
'GTA': 'Val', 'GCC': 'Ala', 'GTC': 'Val', 'GCG': 'Ala', 'GTG': 'Val',
'TTC': 'Phe', 'GTT': 'Val', 'GCT': 'Ala', 'ACC': 'Thr', 'TGA': 'STOP',
'TTG': 'Leu', 'TCC': 'Ser', 'TAA': 'STOP', 'TCT': 'Ser'} # ATG also START
答案 2 :(得分:2)
有多种方法可以做到这一点,最好的方法取决于你seq
在现实生活中的重要程度。其他答案提供了一些很好的方法来利用Python功能来避免明确地构建列表。
我将为您提供一个解决方案,该解决方案遍历每组三个连续字母,但根据i%3
是0
,1
将其分配给三个数组中的一个或2
。
对于您给出的示例 - 对我而言,这很容易阅读,但大致保留了您开始使用的数据结构,我认为这是熟悉的。我冒昧为dict
添加截断的codons
,以便代码运行。
codons = {'atg':'Methionine','tgg':'Tryptophan','ggg':'Glycine',
'ggc':'Glycine','gcc':'Alanine','ccc':'Proline'}
seq='atgggggggcccccc'
seqlen= len(seq)
aaseq=[[],[],[]]
for i in range(seqlen-2):
codon = seq[i:i+3]
aa = codons[codon]
aaseq[i%3].append(aa)
print 'aaseq1 ='
print ''.join(aaseq[0])
print 'aaseq2 ='
print ''.join(aaseq[1])
print 'aaseq3 ='
print ''.join(aaseq[2])
这给出了输出:
aaseq1 =
MethionineGlycineGlycineProlineProline
aaseq2 =
TryptophanGlycineGlycineProline
aaseq3 =
GlycineGlycineAlanineProline
如果你想要一个更简洁的形式 - 试试这个:
#Make every codon by zipping the sequence offset by one each time
codon_sequence = [''.join(z) for z in zip(seq,seq[1:],seq[2:])]
#Print every 3rd codon - starting at zero...
print 'aaseq1 = ',''.join([codons[c] for c in codon_sequence[::3]])
#...then starting at 1...
print 'aaseq2 = ',''.join([codons[c] for c in codon_sequence[1::3]])
#...you get the picture...
print 'aaseq3 = ',''.join([codons[c] for c in codon_sequence[2::3]])
当然 - 如果您需要进行进一步处理,可以将序列分配给变量,而不是将序列打印为最后一步。