在python中使用带有多个变量的for循环

时间:2015-10-02 02:38:36

标签: python

我正在编写一个程序,我希望在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个变量(jk),它们分别从1和2运行并追加aaseq2aaseq3列表中的结果。

 codon2 = seq[j:j+3]
 codon3 = seq[k:k+3]

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%301将其分配给三个数组中的一个或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]])

当然 - 如果您需要进行进一步处理,可以将序列分配给变量,而不是将序列打印为最后一步。