肉渣教程

循环语句

上一节 下一节

Python中的循环语句主要包括for循环、while循环,其中for循环语句最为常用,大多情况下都会优先使用for循环来遍历列表、集合或字典。


初识循环语句

先举一个例子,如果需要输出0-3之间所有的整数(包括0和3),按之前学的则如下所示:

print 0
print 1
print 2
print 3

运行一下


好在这里输出的只是4个整数,那如果需要输出0-100之间所有的整数(包括0和100),那该怎么办呢?手动输出那就太累了;因此这时就可以使用循环语句了:

for i in range(101):
    print i

运行一下


在上述例子中的range是python的内置函数,range(end)可以生成由0到整数end之间所有整数、从小到大排列而构成的列表对象。(包括0,但不包括整数end

>>> range( 4 )
[0, 1, 2, 3]
>>> range( 10 )
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range( 101 )
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]

运行一下


上述例子中传入range函数中只有一个整数n;但其实range函数是可以同时传入两个整数参数的,格式是range(start, end),start和end分别代表起始的整数,可生成从整数start到整数end之间所有的整数、从小到大排列而构成的列表对象。(包括整数start,但不包括整数end;若整数start大于等于整数end,则返回空列表。)

>>> range( 1, 4 )
[1, 2, 3]
>>> range( 99, 101 )
[99, 100]
>>> range( 3, 1 )
[]

运行一下


最后说一个好的习惯,在python2的循环语句中,如果需要用到range函数,请使用xrange函数代替;对于for循环而言,效果是完全一致的,且xrange的效率更高。因为range返回的是一个列表对象,而xrange返回的是一个迭代器;若传入range函数的整数形参极其大,则会返回一个很大的列表对象,这个列表对象会对内存占用相对更多;而面对很大的整数传入,xrange就非常轻松,再大的证书,返回的都只是一个迭代器,占用的内存空间是相对固定有限的。因此,对于for语句而言,xrange比range是更加贤良淑德的选择,因此,现在就可以立刻将range打入冷宫了。

for i in xrange(4):
    print i

for i in xrange(1, 4):
    print i

运行一下


Python的循环语句中还可以对range或xrange传入第三个参数,即步长,默认的步长是1。所谓步长就是下次循环比当前循环时,循环变量的增量值。详情可查看这里


for循环的构建

for循环的本质是迭代一切可以被迭代的对象,比如range构建的列表对象;xrange构建的迭代器对象;字符串、元组等也是可以被迭代的对象;集合和字典也可以被循环迭代,只是迭代的顺序是无逻辑可言的。而循环语句另外一个重要的构成则是冒号和循环内代码块的缩进;老规矩、老标准,请统一使用4个空格,作为一层缩进。

for 迭代变量 in 被迭代的对象:
    代码块


对字符串对象进行迭代:

>>> for c in "zhuan":
...     print c
... 
z
h
u
a
n

运行一下


对列表对象进行迭代:

>>> for e in [ "zhuan", "fou", 666 ]:
...     print e
... 
zhuan
fou
666

运行一下


对集合对象进行迭代(迭代顺序无逻辑可言):

>>> s = { 3, 1, 2 }
>>> for i in s:
...     print i
... 
1
2
3

运行一下


对字典对象进行迭代(迭代顺序无逻辑可言):

>>> d = { "zhuan": "fou", "feng": "yun", "xiong": "ba" }
>>> for key in d:
...     print key, d[ key ]
... 
feng yun
xiong ba
zhuan fou

运行一下


通过for循环对字典对象的迭代遍历,还可以借助字典对象的内置方法iteritems来构建同时包含键(key)与值(value)的迭代器,更多可查看这里


更新被迭代的对象

在循环中,被迭代的对象需要被更新修改时,那就尽量使用计数循环的方式来进行遍历吧。举一个例子,将指定列表对象a中的每一项数字翻2倍;则如下所示,len(a)获得是列表a的元素个数4,for循环迭代的是列表索引构成的迭代器,依次是0、1、2、3;而a[i]则是指定当下循环所对应的a列表中的元素,这时就可以对它进行更新赋值了:

>>> a = [ 3, 7, 8, 2 ]
>>> for i in xrange( len(a) ):
...     a[ i ] *= 2
... 
>>> a
[6, 14, 16, 4]

运行一下


为了进一步让体会通过循环语句更新被迭代对象,特在每一次循环中输出列表a,这样看起来更直观动态一些:

>>> a = [ 3, 7, 8, 2 ]
>>> for i in xrange( len(a) ):
...     a[ i ] *= 2
...     print i, a
... 
0 [6, 7, 8, 2]
1 [6, 14, 8, 2]
2 [6, 14, 16, 2]
3 [6, 14, 16, 4]

运行一下

enumerate函数

如果在for循环中,想同时迭代目标对象的索引和索引对应的元素,那么就可以运用python的内置函数enumerate来轻松实现。

>>> a = [ 3, 7, 8, 2 ]
>>> for i, item in enumerate( a ):
...     print i, item
... 
0 3
1 7
2 8
3 2

运行一下


该函数不仅可以针对列表、元组,还可以针对字符串:

>>> a = "zhuan"
>>> for i, item in enumerate( a ):
...     print i, item
... 
0 z
1 h
2 u
3 a
4 n

运行一下

for循环的嵌套

先说一个例子吧,阶乘应该都不陌生,正整数n的阶乘被简写成n!,而n的阶乘就是1乘以2,再乘以3,依次乘以到n结束,即n! = n * (n-1) * (n-2) * ... * 2 * 1。如果用python来求变量n的阶乘,则如下所示,使用一个循环语句即可:

n = 5
result = 1

for i in xrange(n):
    result *= (i+1)

print result

运行一下


那如果设s = n! + (n-1)! + ... + 2! + 1!,给出指定的正整数n,用python来求取s的值,那该怎么办呢?用两层循环即可。(这里主要是着重介绍循环语句的嵌套,暂不考虑效率和算法)

n = 5
s = 0

for ni in xrange(n):
    result = 1
    for i in xrange(ni + 1):
        result *= (i+1)
    s += result

print s

运行一下


上面的这个例子可能对初学者来说有点复杂,初学者若是不理解,不用理解那么透彻;这里只是想说明循环语句内还可以继续嵌套循环语句。


while循环

while循环的构建方式:

while 条件:
    代码块


上面相对向右缩进的代码块就是循环内的语句,只要条件成立,这个循环就会一直重复下去;直到条件不成立,则立刻结束循环;若从一开始条件就不成立,那while循环内语句就1次也不会被执行。示例代码如下:

>>> a = 0
>>> while a < 5:
...     print a
...     a += 1
... 
0
1
2
3
4

运行一下

无限循环

先举一个无限循环的示例:

while True:
    print "zhuanfou.com"

while循环中,若条件一直成立,那就会一直重复下去,形成死循环,也就是无限循环。针对无限循环,要说如下两点:

  1. 有时会因为失误造成死循环而导致程序无法结束,这时可使用ctrl+C来强制结束程序;
  2. 有时是故意无限循环,让程序一直运行下去的;这时最好将程序在后台运行,免得因为关闭终端而程序结束。

计算机程序不是绝对可靠的,理论正确的程序也有挂的可能性,要有这个敬畏的心理;这个世界上是不存在100%可靠的程序,99.999%也和100%是有区别的。尤其是计算机程序相对于更底层的电子科学、微电子科学领域所说的程序,计算机领域的程序进程的可靠性相对最弱,因为受干扰因素更多,与后者并非一个层级上的可靠。以上述的无限循环程序为例,就算是系统内存、存储空间、CPU资源等各种资源充分有余的情况下,这样一个理论上极其完美的Python程序,理论上是会一直运行下去,但是也会挂的;挂的原因是多元的;神知道!而人只需要知道这些程序是有可能挂的。相应的在不同的场景下,就会有相应的运维措施。比如有个运维工具叫supervisor,就是用来自动监视进程是否挂掉,挂掉了supervisor就会自动重启该程序。是不是很棒呀!其实,supervisor也是有挂的可能性。


循环语句的控制

循环语句还存在一些语句是用来控制循环的,主要有以下三种:

  • break语句 - 跳出当前一层循环
  • continue语句 - 结束本轮循环,继续下一轮循环
  • return语句 - 该语句是用来跳出结束当前函数,因此也顺带间接具有控制循环语句的功能


break语句可立刻跳出结束当前所在的这一层循环:

>>> for i in xrange(100):
...     print i
...     if i > 3:
...         break
... 
0
1
2
3
4

运行一下


continue语句的作用是结束当前一轮的循环,继续下一轮循环。示例如下:

>>> for i in xrange(4):
...     if i == 2:
...         continue
...     print i
... 
0
1
3

运行一下


不管是break语句还是continue语句,其作用的只是其所在的当前一层循环;这点在多层循环嵌套的情况下要格外注重。


推导式

之所以说python语言非常优雅,推导式则是一个非常好的体现。通过推导式,可用非常简短的方式来创建列表、字典、集合等,而且逻辑上看上去更加一目了然,举例如下。

列表推导式

>>> a = [ i * 10 for i in xrange(10) ]
>>> a
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

运行一下


集合推导式

>>> a = { i * 10 for i in xrange(10) }
>>> a
set([0, 70, 40, 10, 80, 50, 20, 90, 60, 30])

运行一下


字典推导式

>>> a = { str(i): chr(i+65) for i in xrange(3) }
>>> a
{'1': 'B', '0': 'A', '2': 'C'}

运行一下


带有条件判断的推导式

>>> a = [ i for i in xrange(10) if i % 2 == 0 ]
>>> a
[0, 2, 4, 6, 8]

运行一下


嵌套的推导式

>>> a = [ (x, y) for x in xrange(3) for y in xrange(3) ]
>>> a
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

运行一下


循环语句

上一节 下一节