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循环的本质是迭代一切可以被迭代的对象,比如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]
如果在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
先说一个例子吧,阶乘应该都不陌生,正整数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循环内语句就1次也不会被执行。示例代码如下:
>>> a = 0 >>> while a < 5: ... print a ... a += 1 ... 0 1 2 3 4
先举一个无限循环的示例:
while True: print "zhuanfou.com"
while循环中,若条件一直成立,那就会一直重复下去,形成死循环,也就是无限循环。针对无限循环,要说如下两点:
计算机程序不是绝对可靠的,理论正确的程序也有挂的可能性,要有这个敬畏的心理;这个世界上是不存在100%可靠的程序,99.999%也和100%是有区别的。尤其是计算机程序相对于更底层的电子科学、微电子科学领域所说的程序,计算机领域的程序进程的可靠性相对最弱,因为受干扰因素更多,与后者并非一个层级上的可靠。以上述的无限循环程序为例,就算是系统内存、存储空间、CPU资源等各种资源充分有余的情况下,这样一个理论上极其完美的Python程序,理论上是会一直运行下去,但是也会挂的;挂的原因是多元的;神知道!而人只需要知道这些程序是有可能挂的。相应的在不同的场景下,就会有相应的运维措施。比如有个运维工具叫supervisor,就是用来自动监视进程是否挂掉,挂掉了supervisor就会自动重启该程序。是不是很棒呀!其实,supervisor也是有挂的可能性。
循环语句还存在一些语句是用来控制循环的,主要有以下三种:
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)]