1、Python for Bioinformatics 4 流程控制Python for Bioinformatics (4)第四章 编程:流程控制 为了能够做一些有用的东西,程序必须有某种机制来管理怎样和何时执行指令。交通灯控制着在街上的车流,以同样的方式,流程控制结构指导代码段在一个给定的时间里执行。 通过大量的简化, Python只有三种流的控制结构:有一个条件结构和两个迭代结构。条件结构(if)决定,在表达式求值后,是执行或不执行代码块。迭代结构允许多次执行相同的代码段。可以执行多少次迭代结构相关的代码呢?它取决于是哪种循环。一个for循环执行一个代码块的次数决定于它指定的迭代量的元素的个
2、数,而在while循环下的代码执行直到给定的条件变成假(注:这等于说,条件为真时执行)。4.1 If-Else 条件结构最经典的控制结构的之一。它的行为根据求值的结果,如果你知道任何其他的计算机语言,你就有机会熟悉if - else。计算一个表达式,如果表达式为真,在if子句后的代码块被执行,否则,在else块中执行。 一个if - else条件的基本模式如下:if EXPRESSION: Block1else: Block2 EXPRESSION必须是一个表达式返回True或False。这是所有比较的运算符情形:xy(大于),x= y(等于),x!= y(不等于)(注:还有一个过期的运算符,
3、你可以在旧的Python版本中找到),x=y(大于或等于)。 来看一个例子:列表4.1: 基本的 if-else 例子1 a = 82 if a5:3 print(a is greater than 5)4 else:5 print(a is smaller than 5) 程序输出:a is greater than 5 另一个例子:列表4.2: 实施if-else1 trans = A:Ala,N:Asn,D:Asp,C:Cys2 aa = raw_input(Enter one letter: )3 if aa in trans:4 print(The three letter code
4、 for +aa+ is: +transaa)5 else:6 print(Sorry, I dont have it in my dictionary) 程序输出:Enter one letter: AThe three letter code for A is: Ala 为了计算一个以上的条件的值,可以使用elif:if EXPRESSION1: Block1elif EXPRESSION2: Block2elif EXPRESSION3: Block3else: Block4 你用多少的elif作为条件来求值都可以。要注意到的是,一旦一个条件为真值时,其余的条件将不会被检查。 下面的程序
5、使用elif计算多个条件:列表4.3: 使用 elif1 dna = raw_input(Enter your DNA sequence: )2 seqsize = len(dna)3 if seqsize 10:4 print(The primer must have at least ten nucleotides)5 elif seqsize a=1 b=1 bool(a=b)False 条件结构可以嵌套:列表4.4: 嵌套if1 dna = raw_input(Enter your DNA sequence: )2 seqsize = len(dna)3 if seqsize 10:4
6、 print(Your primer must have at least ten nucleotides)5 if seqsize=0:6 print(You must enter something!)7 elif seqsize answer=42 answer42 answer=3False answer=42True 在代码4.4中引入的if嵌套可以避免:列表4.5: 嵌套 if1 dna = raw_input(Enter your DNA sequence: )2 seqsize = len(dna)3 if seqsize=0:4 print(You must enter so
7、mething!)5 elif 0seqsize10:6 print(Your primer must have at least ten nucleotides)7 elif seqsize 25:8 print(This size is OK)9 else:10 print(Your primer is too long) 注意第5行表达式的计算形式。这让我们想到如何在一个if中加入多个声明,像代码4.6的例子:列表4.6: 多部分条件1 x = N/A2 if x!=N/A and 5float(x)20:3 print(OK)4 else:5 print(Not OK) 这个表达式是从
8、左至右求值的,如果一个表达式的一部分是假的,以下部分不计算。由于X =“N/ A”,该程序将打印“Not OK”(因为第一个条件是假的)。看看相同的表达式是按反向顺序书写会发生什么?这是程序:列表4.7: 多部分的条件,反向x=N/Aif 5float(x)20 and x!=N/A: print(OK)else: print(Not OK)返回结果是:Traceback (most recent call last):File , line 1, in if 5float(x) print(Average = %s%(t/n if n!=0 else N/A) 来替代if n!=0:prin
9、t(Average = %s%(t/n)else:print(Average = N/A)4.2 For循环 这种控制结构使代码被重复执行,并同时保有一个可迭代的对象(注:最常见的可迭代的对象是:列表,元组,字符串和字典。文件和定制的对象,也可迭代的。)的值的变量。一个for循环的一般形式是for VAR in ITERABLE: BLOCK 在迭代量ITERABLE后有冒号。这是强制性的,作为缩进的代码块,是for循环的一部分。这种结构的结果是导致BLOCK和在迭代的对象的元素数目一样多的次数的重复。在每次迭代中,VAR需要取ITERABLE在当前元素的值。在下面的代码中,for通过一个列表
10、(bases)遍历四个元素。在每次迭代中,x的值是列表中的元素之一。 bases = C,T,G,A for x in bases:. print(x).CTGA 在其他语言中,for循环是用来控制一个代码块运行的次数,同时改变一个计数器变量。这种行为可以在Python通过迭代一个数字的列表被重建: for x in 0,1,2,3:. print(str(x)+*+str(x)+ = +str(x*x).0*0 = 01*1 = 12*2 = 43*3 = 9 生成列表的快捷方式是通过使用内置的功能range(n)。此函数返回与第一个输入参数一样多的元素列表(注:所有的内置函数在D.6,页4
11、94中介绍), for x in range(4):. print str(x)+*+str(x)+ = +str(x*x).0*0 = 01*1 = 12*2 = 43*3 = 9 下面的代码是基于单个氨基酸计算蛋白质的分子量。(注:氨基酸是蛋白质的组成部分。每个氨基酸(由字母代表)都有一个分子量。因为每个氨基酸键脱掉一个水(水分子量是18),脱去水的分子量被总量中减去。)因为氨基酸是在一个字符串中,该程序将使用for通过每个字母遍历,列表4.8:用for计算蛋白质的分子量(py3.us/2)1 protseq = raw_input(Enter your protein sequence:
12、 )2 protweight =A:89,V:117,L:131,I:131,P:115, F:165,3 W:204,M:149,G:75,S:105,C:121,T:119,4 Y:181,N:132,Q:146,D:133,E:147,5 K:146,R:174,H:1556 totalW = 07 for aa in protseq:8 totalW = totalW + protweight.get(aa.upper(),0)9 totalW = totalW-(18*(len(protseq)-1)10 print(The net weight is: +str(totalW) 代
13、码解释:在第一行要求用户输入蛋白质序列(例如MKTFVLHIFIFALVAF)。由raw_input返回的字符串被命名为protseq。从第2 行至5行,让氨基酸分子量字典(protweight)初始化。在第7行使用一个for循环来遍历每个protseq元素。在每次迭代中,aa从 protseq从取一个元素的值,这个值是用来搜索protweight字典的。一个周期后,totalW最终得到所有氨基酸的重量的总和。在第9行进行一个修正,是基于这样的事实,每个键涉及一个水分子(分子量18)的损失。最后一行打印出的净重量。4.3 While循环 这个循环非常类似for循环,因为它也是在以反复的方式执行
14、代码部分。在这里,没有一个迭代的对象,这个循环不会以迭代遍历对象方式结束,而是通过给定一个条件是不真时结束。while循环模型如下:while EXPRESSION: BLOCK 考虑到在块内应该有一条指令使条件为假, 这是非常重要的,否则,可能会进入一个无限循环: a=10 while a a=10 while True:. if a40:. print a. else:. break. a += 10.102030 这样做是为了确保至少执行一次循环内的程序块。在其他语言中有单独为这种情况设计的循环类型(do while),但它目前在Python不存在。(注: 有一个建议是添加这种结构到Py
15、thon中,见文档PEP- 315(http:/www.python.org/dev/peps/pep-0315),但它没有实施的日期,因此不要依赖于这个结构。)4.4 Break:中断循环 Break是用来摆脱一个循环结构的。我们已经看到的在while中用法的例子,但它也可以应用于for循环。 起初并不容易认识到使用break语句实际上是有意义的。举个例子,代码4.9列表4.9: 在一列元组中搜索一个值1 cc = (red,1), (green,2), (blue,3), (black,4)2 name = blue3 for colorpair in cc:4 if name=color
16、pair0:5 code = colorpair16 print code 在这段代码中有一个for循环遍历cc列表。对于每个元素,也就是说,每个元组,会检查它的第一个元素。当它符合我们的查询(name),程序代码存储到相关的值到code,所以这个程序的输出只是“3”。 这个程序的问题是,即使我们不需要,整个序列被遍历了。在这种情形下,在第4行的条件对cc中的每个元素一次评估时,很显然,一旦匹配是阳性的,就没有必要继续测试。你可以通过在阳性匹配后中断循环,来节省一些时间和处理能力:列表4.10: 在一列元组中搜索一个值1 cc = (red,1), (green,2), (blue,3), (
17、black,4)2 name = blue3 for colorpair in cc:4 if name=colorpair0:5 code = colorpair16 break7 print code 此代码与4.9是相同的,除在第6行的break语句。输出是像以前一样,但这个时候你不需要浪费CPU周期没有理由地迭代一个序列。在这个例子中保存的时间是微不足道的,但如果程序有一个大的列表或文件(你也可以遍历文件)需要遍历几次,break可以显著地加快它的运行了。 break的使用是可以被避免的,但生成的代码也不是如程序4.10那么清晰可辨:列表4.11: 在一列元组中搜索一个值1 cc =
18、(red,1), (green,2), (blue,3), (black,4)2 name = blue3 i = 04 while name!=cci0:5 i += 16 code = cci17 print code_ 在这个例子中,列表可以很容易地被装入内存,更好的主意是创建一个字典来查询它:列表4.11: 用字典在一列元组中搜索一个值1 cc = (red,1), (green,2), (blue,3), (black,4)2 name = blue3 cc_d = dict(cc)4 print cc_dname4.5总结在一起 把if,for, while和现在看到的数据结构结合
19、在一起,在这里,我展示一些用我们刚刚学到的工具写的小程序:4.5.1估计一种蛋白质的净电荷 在一个固定的pH值下,可以通过把单个氨基酸的电荷加起来,计算蛋白质的净电荷。这是一个近似值,因为它没有考虑到暴露或埋藏在蛋白质结构下的氨基酸。它还没有考虑到半胱氨酸只有当它不是一个二硫键的一部分时才添加电荷这一事实。因为它是一个近似的值,所以获得的值应被视为一种估计。 这里是第一个版本的protnetcharge.py:列表 4.13: 一种蛋白质的净电荷 (py3.us/3)1 protseq = raw_input(Enter protein sequence: )2 charge = -0.0023 AACharge = C:-.045,D:-.999,E:-.998,H:.091,4 K:1,R:1,Y:-.0015 for aa in protseq:6 if aa in AACharge:7
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1