Python学习笔记:04 循环

来源:互联网 发布:数据分析基础 教材 编辑:程序博客网 时间:2024/06/07 03:28

本篇介绍Python的while循环和for循环。可以在如下位置下载代码文件:
https://code.csdn.net/snippets/188632/master/LoopTest.py/raw

基本while循环

print '###############'print 'Basic while loop:'i = 0while i < 5:    print 'i =', i    i += 1print ''


C风格的“整型做为循环条件”

print '################'print 'Integer as boolean:'i = 5while i:    print 'i =', i    i -= 1print ''


while带多个条件

while后面可以是任意的布尔表达式,只要确保整个表达式最后能返回一个布尔值就可以了:
print '######################################'print 'While loop with multiple conditions:'i, j = 0, 0while i < 3 or j < 5:    print 'i =', i, ', j=', j    i += 1    j += 1print ''

用for循环遍历数组等对象

在其它很多语言中,如果我们定义了一个形如“myArr = {10, 11, 12, 13 ,14}”这样的数组,当用for循环来遍历这个数组时,必须引入一个控制变量(例如下面例子中的“i”):
for (int i; i = 0; i < myArr.length){    currItem = myArr[i]    process(currItem)    i++}
变量i被用于控制循环次数,同时用来取当前位置的数组元素。

不同于其它语言,Python中的for循环并非while循环的一种替代。Python中的for循环是专门用于遍历iterable(数组的一种),而不需要引入专门的控制变量。
for循环必须与“in”关键字连用。样例代码如下:
myArr = (10, 11, 12, 13, 14)for currNum in myArr:    print currNum

注:
* for ... in ... 语句是用于遍历一个iterable类型的对象,和直接的 ... in ... 语句是不同的,后者是查找“in”前面的值是否在“in”后面的iterable对象中存在,并返回布尔值。

使用for循环时,同时获取当前的循环位置

Python的for循环虽然省去了引入控制变量,但有时候我们确实需要获取当前循环到第几次,可以使用内置的“enumerate”对象来包装:
print '#########################################################'print 'Get current index when using for loop:'myArr = (10, 11, 12, 13, 14)for idx, currNum in enumerate(myArr):    print "Current index: %s, current item: %s" % (idx, currNum)print ''

注:
* 关于enumerate,将在以后介绍
* 关于for后面带2个变量,在紧接着的下面介绍。

快速遍历已知列数的“矩阵”形式的二维数组

print '#######################################'print 'Get all value of a matrix:'myArr = ((10, 11), (20, 21), (30, 31))for var1, var2 in myArr:    print "arg1: %s, arg2: %s" % (var1, var2)print ''

注:
* “((10, 11), (20, 21), (30, 31))”定义了一个3行2列的二维数组(确切地讲,是二维“元组”)
* for语句后面跟的参数个数,必须小于或等于每一个内层数组的个数,否则,运行时将会出现数组越界的错误

遍历String中的每一个字符
事实上,不仅是数组,所有可进行Iterate的对象,都可以用for ... in ... 语句来遍历。如下就展示了如何遍历一个String:
print '#################################'print 'Get each character of a String:'myStr = "This is my String"for char in myStr:    print 'Current char:', char

在以后的使用中,可能还会遇到各种可Iterate的对象,它们都可以与类似上面的形式来操作。

跳转(break、continue)

这一部分和其它语言基本类似,熟悉的话可以跳过。

使用continue跳过循环块中所有的剩余代码,立即重新回到循环块的开始(即下面例子中,立即执行“while i < 4:”这行代码)
print '#########################'print 'Test of continue:'print 'Loop start'i, j = -1, -1while i < 4:    j += 1    i += 1    if j == 2:        print 'j =', j        continue    print 'i =', i, ', j =', jprint 'Loop finish'print ''

使用break跳过循环中所有的剩余代码,立即执行循环块后的代码(即下面例子中,立即执行“print 'Loop finish'”这行代码)
print '#######################'print 'Test of break:'print 'Loop start'i, j = -1, -1while i < 4:    j += 1    i += 1    if j == 2:        print 'j =', j        break    print 'i =', i, ', j =', jprint 'Loop finish'print ''

话题:多层嵌套的跳转

在这个问题上,可能很多人要失望了。Python不仅不支持goto,连使用label来直接跳出一个多重循环都不允许。考虑这个场景:检查一个不定长的二维数组中,是否存在至少1个“python”字符串。这种情况下只要发现第一个目标字符串,剩下来的循环就都不需要执行了。假设该数组为:
(('Now', 'we', 'are'), ('going', 'to'), ('introduce', 'you', 'the', 'python', 'programming', 'language.'))

如下代码可以实现该需求:
print '################################################################################'print 'Test of nesting break:'print 'First test:'myArr = (('Now', 'we', 'are'), ('learning', 'the', 'Python', 'programming', 'language'),         ('which', 'is', 'very', 'powerful.'))for each_tuple in myArr:    for each_str in each_tuple:        print 'Now checking string:', each_str        if each_str == 'Python':            print 'Found!'print 'finished!'

观察运行发现,尽管找到了'Python'之后,程序已经达到了目的,但是它仍继续对后续字符串进行了判断——而这完全是在浪费时间。

按照传统语言,可以使用goto来避免这种浪费(如下代码在Python中不可执行):
myArr = (('Now', 'we', 'are'), ('learning', 'the', 'Python', 'programming', 'language'),         ('which', 'is', 'very', 'powerful.'))for each_tuple in myArr:    for each_str in each_tuple:        print 'Now checking string:', each_str        if each_str == 'Python':            print 'Found!'            goto: endend: print 'finished!'

即使像Java这种不支持goto的语句,也支持为代码块打标签,配合continue、break这类跳转语句来实现,例如(如下代码在Python中不可执行):
myArr = (('Now', 'we', 'are'), ('learning', 'the', 'Python', 'programming', 'language'),         ('which', 'is', 'very', 'powerful.'))check: for each_tuple in myArr:    for each_str in each_tuple:        print 'Now checking string:', each_str        if each_str == 'Python':            print 'Found!'            break: checkprint 'finished!'

然而,令人失望的是,Python对上述2种方式都不支持。曾经有人建议Python支持这种方式,但是被拒绝了。在现有条件下,有一些替代的方法可以来实现

添加控制语句

print '2. Break with control variable:'found = Falsefor each_tuple in myArr:    for each_str in each_tuple:        print 'Now checking string:', each_str        if each_str == 'Python':            found = True            print 'Found!'        if found:            break    if found:        break

这里,我们引入了一个控制变量“found”,赋初值为False。并在每个循环体的最后都添加一个判断,一旦发现它为真,则break。然后在程序执行中,任何地方只要想结束本次循环,就直接讲其置为True即可。
它的问题在于如果你的循环很深,你需要添加很多个这种if语句来判断。并且添加太多的重复语句,容易导致代码在后续修改时容易出错,不易维护。不过这种方法目前看来是最好的方法。

使用异常

print '3. Break with exception:'try:    for each_tuple in myArr:        for each_str in each_tuple:            print 'Now checking string:', each_str            if each_str == 'Python':                found = True                print 'Found!'                raise ValueError("Found!")except ValueError:    passprint 'finished!'print ''

注:
* 这种方式是最接近label break的方式。
* 一般在Python界认为这种方式是“不够文雅”的,因为异常用于非预期的情况,而实际上此处代码是正常处理的。
* 如果确实要用异常来处理,应该建立一个自定义的异常类而不要像本代码中展示的使用系统的“ValueError”,因为这可能导致确实出现这种异常时没有正确处理。关于自定义异常,可以参考后面的说明。

0 0