页面导航:
英文教程的下载地址:
本篇文章是根据英文教程《Python Tutorial》来写的学习笔记。该英文教程的下载地址如下:
百度盘地址:
http://pan.baidu.com/s/1c0eXSQG
DropBox地址:
点此进入DropBox链接
Google Drive:
点此进入Google Drive链接
这是学习笔记,不是翻译,因此,有些内容,作者会略过。以下记录主要是根据英文教程的第七章来写的。(文章中的部分链接,可能需要通过代理访问!)
概述:
如果要将一段代码反复执行多次的话,在python中可以使用while或for循环语句来实现,下面就对这两种循环语句分别进行介绍。(下面内容中提到的
"对象"的概念,在之前的
"Python基本的操作运算符"章节的
比较运算符部分已经介绍过了,这里就不多说了)
while循环语句:
while语句的语法,如下所示:
while expression:
statement(s)
|
和if类似的是:while后面的expression可以是任意类型的表达式,比如a * b 或 a > b之类的。当表达式返回的对象是True时,就会执行while下面的statement(s)代码块,执行完statement(s)后,又会回到while的开头,继续判断expression表达式是否为True,为True就再次执行statement(s)代码块,执行后又继续判断expression,就这样一直循环下去,直到expression返回False,或者statement(s)代码块里执行了break语句为止(break语句后面会介绍),才会跳出循环。
和if一样,非零的数字、非空的字符串、或非空的集合,都可以当作True。而零、空字符串、空集合、None,则可以当作False。
下面是while语句的完整例子:
#test.py
count = 0
while (count < 9):
print 'The count is:', count
count = count + 1
print "Good bye!"
|
上面代码中,count变量的值一开始是0,那么while刚开始执行时,表达式count < 9就会返回True,这样,while下面的代码块就会被执行,代码块中有两条语句,第一条print语句用于将count的当前值显示出来,第二条语句则会将count的值加1,这样count的值就会由0变为1,代码块执行完后,又会回到while的开头部分,并重新对count < 9进行判断,由于count的值为1,还是小于9,因此,while下面的代码块又会被执行,执行完后,count就变为2了,并继续与9进行判断,因为小于9,又可以执行一次代码块,这样一直循环执行下去,当count递增到9时,由于count等于9,那么此时,count < 9的表达式就会返回False,这样就跳出while循环了。
跳出循环后,如果while后面还有可供执行的代码,就执行这些代码,如上面的最后一条print
"Good bye!"语句,它和
while具有相同的缩进,因此是
while后面可供执行的代码,它就会被执行。
我们可以将上面的代码保存到test.py文件中,然后用python解释器来解释执行该文件,运行结果如下:
[email protected]:~/Pytest/ch7$ python test.py
The count is: 0
The count is: 1
The count is: 2
The count is: 3
The count is: 4
The count is: 5
The count is: 6
The count is: 7
The count is: 8
Good bye!
[email protected]:~/Pytest/ch7$
|
和if语句的注意事项类似:while语句也必须以冒号结束。
无限循环:
当while后面的表达式始终返回True,且代码块中又没有break语句来跳出循环时,while就会处于无限循环状态,也就是while下面的代码块会永无止尽的反复被执行,除非程序被系统强行终止,如下例所示:
#test_infinite.py
var = 1
while var == 1 : # This constructs an infinite loop
num = raw_input("Enter a number :")
print "You entered: ", num
print "Good bye!"
|
上面的变量var的值始终为1,因此,while后面的var == 1的表达式始终会返回True,这样,while下面的代码块就会一直反复的执行下去。该代码块由两条语句构成:第一条语句会通过raw_input函数,提示用户输入一个数字,并返回该数字,以保存到num变量中。第二条语句会通过print关键字将之前用户输入的数字给显示出来。由于是无限循环,所以上面代码中的最后一条
print "Good bye!" 语句永远不会被执行。
我们将上面代码保存到test_infinite.py文件中,运行结果如下:
[email protected]:~/Pytest/ch7$ python test_infinite.py
Enter a number :1
You entered: 1
Enter a number :2
You entered: 2
Enter a number :3
You entered: 3
Enter a number :4
You entered: 4
Enter a number :5
You entered: 5
Enter a number :6
You entered: 6
Enter a number :7
You entered: 7
Enter a number :8
You entered: 8
Enter a number :^CTraceback (most recent call last):
File "test_infinite.py", line 5, in <module>
num = raw_input("Enter a number :")
KeyboardInterrupt
[email protected]:~/Pytest/ch7$
|
上面这种无限循环的情况,在linux命令行下,可以通过CTRL+C的按键组合来强行终止程序的运行。
while...else语句:
在Python中有一种很特殊的语句,就是 while...else 语句,在其他语言里,很难看到这种结构。该语句的语法如下:
while expression:
while_statement(s)
else:
else_statement(s)
|
当expression表达式返回的对象为True时,它会循环执行while_statement(s)代码块,直到expression表达式判断为False时,它才会去执行else_statement(s)代码块。此外,当while_statement(s)代码块中通过break语句跳出循环时(break语句在后面会介绍),是不会去执行else_statement(s)代码块的。例如下面的例子:
#test_while_else.py
count = 0
while count < 5:
print count, " is less than 5"
count = count + 1
else:
print count, " is not less than 5"
|
上面代码中,count一开始为0,因此,while后面的count < 5的表达式会返回True,然后执行while下面的代码块,在该代码块中会显示一条"... is less than 5"的信息,并将count的值加1,所以,while下面的代码块会被反复执行5次,直到count递增到5时,表达式 count < 5 才会返回False,此时才会去执行else下面的print语句。
我们将上面代码保存到test_while_else.py文件中,运行结果如下:
[email protected]:~/Pytest/ch7$ python test_while_else.py
0 is less than 5
1 is less than 5
2 is less than 5
3 is less than 5
4 is less than 5
5 is not less than 5
[email protected]:~/Pytest/ch7$
|
单行while语句:
与if语句类似的是,当while的循环体代码块中,只包含一条语句时,可以将该语句和while写在同一行:
[email protected]:~/Pytest/ch7$ python
Python 2.7.8 (default, Dec 10 2014, 22:05:07)
[GCC 4.5.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> while(False): print 'I will not run!'
...
>>> quit()
[email protected]:~/Pytest/ch7$
|
上面的交互式输入中,while后面的表达式部分用的是False来做演示,这是因为,当使用True时,这段代码一执行就会陷入无限循环,这种情况下就只有通过CTRL+C来强行终止了。
当while的代码块中包含多条语句时,要想将这些语句也和while写在同一行的话,就需要在各语句之间加入分号来隔开:
[email protected]:~/Pytest/ch7$ python
Python 2.7.8 (default, Dec 10 2014, 22:05:07)
[GCC 4.5.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> count = 0
>>> while count < 5: print count,"is less than 5"; count = count + 1
...
0 is less than 5
1 is less than 5
2 is less than 5
3 is less than 5
4 is less than 5
>>> quit()
[email protected]:~/Pytest/ch7$
|
for循环语句:
Python中的for语句是用于对字符串、列表、元组之类的集合进行成员迭代的(字符串可以看作是由字符组成的集合),所谓迭代就是:每次从集合中提取一个成员,然后在代码块中,就可以对提取出来的成员做些相应的处理了,迭代会按照一定的顺序,将集合中的所有成员都提取出来。for语句的具体语法如下:
for iterating_var in sequence:
statements(s)
|
上面语法中,
for 和
in 是该语句里的两个固定的关键字,for语句执行的时候,第一次会从sequence集合中提取出第一个成员,并将该成员赋值给iterating_var变量,接着,就会去执行for下面的statements(s)代码块,执行完代码块后,又会回到开头的for...in部分,从sequence集合中提取出第二个成员,并赋值给iterating_var变量,再去执行statements(s)代码块,这样循环下去,直到sequence集合中的最后一个成员被提取出来,并经过了statements(s)处理后,才会结束循环。
以下是英文教程中,有关for语句的Flow Diagram(流程图):
图1
这幅流程图形象的说明了for语句的执行过程,它会对sequence集合中的每个Item成员执行一次statement(s)代码块,当no more item(没有更多的成员,即所有成员都处理过了)时,就会结束循环,而去执行for后面的代码了。
此外,当statements(s)代码块中执行了break语句时(break后面会介绍),可以直接结束for循环。
以下是for语句的完整的例子:
#test_for.py
for letter in 'Python': # First Example
print 'Current Letter :', letter
fruits = ['banana', 'apple', 'mango']
for fruit in fruits: # Second Example
print 'Current fruit :', fruit
print "Good bye!"
|
上面的代码里,有两个for语句,第一个for语句用于将
'Python'字符串里的每个字符依次提取到letter变量中,每提取一个字符,就执行一次print语句,将letter显示出来。第二个for语句用于对fruits列表进行迭代,并将迭代出来的每个成员打印显示出来。将上述代码保存到test_for.py文件中,运行结果如下:
[email protected]:~/Pytest/ch7$ python test_for.py
Current Letter : P
Current Letter : y
Current Letter : t
Current Letter : h
Current Letter : o
Current Letter : n
Current fruit : banana
Current fruit : apple
Current fruit : mango
Good bye!
[email protected]:~/Pytest/ch7$
|
对于列表而言,由于列表中的每个元素都对应有一个索引值,因此,在for循环中也可以通过索引值来进行迭代,例如,下面的例子:
#test_index.py
fruits = ['banana', 'apple', 'mango']
for index in range(len(fruits)):
print 'Current fruit :', fruits[index]
print "Good bye!"
|
要理解上面代码的含义,首先要理解代码中出现的len函数与range函数的作用。len函数的作用是:当len函数的参数是集合时,它可以返回该集合中的成员数量:
[email protected]:~/Pytest/ch7$ python
Python 2.7.8 (default, Dec 10 2014, 22:05:07)
[GCC 4.5.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> fruits = ['banana', 'apple', 'mango']
>>> len(fruits)
3
>>> quit()
[email protected]:~/Pytest/ch7$
|
上面fruits列表中有'banana'之类的三个成员,因此
len(fruits)函数返回的值就是3 。
range函数的作用,可以通过help函数来查询到:
[email protected]:~/Pytest/ch7$ python
Python 2.7.8 (default, Dec 10 2014, 22:05:07)
[GCC 4.5.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> help(range)
Help on built-in function range in module __builtin__:
range(...)
range(stop) -> list of integers
range(start, stop[, step]) -> list of integers
Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!
These are exactly the valid indices for a list of 4 elements.
(END)
>>> range(3)
[0, 1, 2]
>>> range(1,3)
[1, 2]
>>> range(1,10,3)
[1, 4, 7]
>>> quit()
[email protected]:~/Pytest/ch7$
|
可以看到,range函数会返回一个由一组等差数构成的列表(等差数列的默认递增值为1),当range函数只有一个参数时,它会返回一个从0开始,到该参数结束的列表(但
不包括该参数在内),例如上面的range(3)就返回的是[0, 1, 2] ,当它接受两个参数时,第一个参数表示起始值,第二个参数表示结束值,同样返回的列表中也
不包括结束值,例如上面的range(1,3)返回的就是[1,2],当它接受三个参数时,第一个参数表示起始值,第二个参数表示结束值,第三个参数表示等差数之间的递增值,例如上面的range(1, 10, 3)返回的就是[1, 4, 7] ,该列表中的三个数为1到10(不包括10)的等差数,递增值为3 。
再来看下之前的索引值的例子:
#test_index.py
fruits = ['banana', 'apple', 'mango']
for index in range(len(fruits)):
print 'Current fruit :', fruits[index]
print "Good bye!"
|
该例子中,
range(len(fruits))返回的结果就是[0, 1, 2]的列表(len函数返回fruits的成员数3,range再将3变为对应的等差数列)。因此,上面的for语句其实就等价于:
for index in [0, 1 ,2]:
print 'Current fruit :', fruits[index]
|
这样,for就会将0,1,2依次赋值给index变量,该变量就可以作为索引值来访问fruits列表中的成员了。将上面的索引值例子保存到test_index.py文件中,运行结果如下:
for...else语句:
else同样可以和for组合在一起使用,构成for...else语句,该语句的语法如下:
for iterating_var in sequence:
for_statement(s)
else:
else_statement(s)
|
上面的语法中,for会先循环执行for_statement(s)代码块,直到sequence集合中的所有成员都被提取出来为止,当sequence集合中没有更多的成员可供提取时,最后才会去执行else下面的else_statement(s)代码块。
需要注意的是:如果for_statement(s)代码块中执行了break语句的话,就可以直接结束for循环,并且不会去执行else_statement(s)代码块。
for...else语句的完整例子,如下所示:
#test_for_else.py
for num in range(10,20): #to iterate between 10 to 20
for i in range(2,num): #to iterate on the factors of the number
if num%i == 0: #to determine the first factor
j=num/i #to calculate the second factor
print '%d equals %d * %d' % (num,i,j)
break #to move to the next number, the #first FOR
else: # else part of the loop
print num, 'is a prime number'
|
上面代码中,有两层for循环,第一层for循环会从[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]的列表中(该列表由range函数生成),依次将这些数字提取出来,并将提取出来的数字赋值给num变量,接着,在第二层for循环里,会依次对num的所有可能的因子进行检测,如果该num不存在能整除的因子的话,就不会触发if代码块里的
break语句,这样,第二层for循环结束时,就会执行else下面的代码块,也就是将该num作为
prime number(即素数)显示出来,如果存在能整除的因子的话,就会执行for循环里的if代码块,该代码块的最后有一个break语句,该break会直接跳出第二层for循环,并且不会执行else下面的代码块,这样,如果num是非素数(或者叫合数)的话,就会只显示出非素数(合数)的相关因子信息,也就是上面的
'... equals ... * ...'的信息。
例如,当num为10时,第二层for语句就相当于 for i in [2, 3, 4, 5, 6, 7, 8, 9] ,第一次将2取出来,10可以被2整除,10和2相除的余数就会是0,因此,if num%i == 0就会判断通过,if代码块会被执行,该代码块中,j=num/i 语句用于计算另外一个可以整除的因子,10/2为5,此时,j的值就会是5,这样 print '%d equals %d * %d' % (num,i,j) 语句就会显示出 "10 equals 2 * 5" 的信息,最后的break语句会直接结束本次for循环(同时跳过else部分),并回到外层for循环,继续去判断下一个数字即11 。
当num为11时,第二层for语句就相当于 for i in [2, 3, 4, 5, 6, 7, 8, 9, 10] ,这些数字都不能整除11,即11是素数,因此,第二层for循环下面的 if num%i == 0 语句就都不会判断通过,if代码块里的break语句就不会被执行,当2到10的数字都被判断过后,最后就会自动触发else下面的代码,也就是将11是素数的信息给显示出来。
将上面的代码保存到test_for_else.py文件中,运行结果如下:
[email protected]:~/Pytest/ch7$ python test_for_else.py
10 equals 2 * 5
11 is a prime number
12 equals 2 * 6
13 is a prime number
14 equals 2 * 7
15 equals 3 * 5
16 equals 2 * 8
17 is a prime number
18 equals 2 * 9
19 is a prime number
[email protected]:~/Pytest/ch7$
|
嵌套循环语句:
从上面的test_for_else.py例子中可以看到,循环结构是可以嵌套的,即for循环里可以再嵌套一个for循环之类的。
下面是嵌套for循环的语法:
for iterating_var in sequence:
for iterating_var in sequence:
statements(s)
statements(s)
|
上面的语法只是一个演示,其实还可以嵌套更多层次的for语句。
while循环语句也是可以嵌套的,嵌套的演示语法,如下所示:
while expression:
while expression:
statement(s)
statement(s)
|
此外,for循环里可以再嵌套while循环,或者反过来,在while循环里嵌套for循环,都是可以的。
以下是嵌套循环语句的完整例子:
#test_nested.py
i = 2
while(i < 100):
j = 2
while(j <= (i/j)):
if not(i%j): break
j = j + 1
if (j > i/j) : print i, " is prime"
i = i + 1
print "Good bye!"
|
上面代码用于从2到100中查找出素数,它的算法比之前介绍的test_for_else.py例子的效率要更高些,因为它只用对其中一部分因子做判断即可,在
http://en.wikipedia.org/wiki/Primality_test 链接中也解释了素数检测的原理,将上面代码保存到test_nested.py文件中,运行结果如下所示:
[email protected]:~/Pytest/ch7$ python test_nested.py
2 is prime
3 is prime
5 is prime
7 is prime
11 is prime
13 is prime
17 is prime
19 is prime
23 is prime
29 is prime
31 is prime
37 is prime
41 is prime
43 is prime
47 is prime
53 is prime
59 is prime
61 is prime
67 is prime
71 is prime
73 is prime
79 is prime
83 is prime
89 is prime
97 is prime
Good bye!
[email protected]:~/Pytest/ch7$
|
控制语句:
控制语句可以改变程序的流程,比如:前面提到的break语句,就可以直接结束循环结构等。在Python中支持以下几个控制语句:
Control Statement
控制语句 |
Description
描述 |
break语句 |
终止当前的循环结构,并转去执行循环语句之后的代码。 |
continue语句 |
直接跳转到循环语句的开头,以重新对条件表达式进行判断,由于跳转到了循环语句的开头,因此continue之后的循环体中的语句不会被执行。 |
pass语句 |
pass在python中不会产生任何实际的操作,它就是一个空语句,因为某些时候,流程控制结构中的代码块,可能不需要执行任何语句,那么就可以在代码块里放置一个pass来表示空语句即可。 |
break语句在之前的例子中,已经被使用过多次,它既可以终止while循环结构,又可以终止for循环结构。只不过需要注意的是:当你在嵌套循环中使用break时,break只会终止最内层的循环,并在终止的循环结构之后,继续执行。例如下面的例子:
for i in [1,2,3,4]:
for j in [4,5,6,7]:
for n in 'hello':
if n == 'e':
print n
break
print j
|
上面的例子中,
break语句在执行时,只会将最内层的
for n
in 'hello': 循环结构给终止掉,并且python会转到其后的
print j 语句开始执行(该print语句与终止的for语句属于同一个代码块),另外两层
for语句不会被
break语句给终止。
以下是break语句的完整例子:
#test_break.py
for letter in 'Python': # First Example
if letter == 'h':
break
print 'Current Letter :', letter
var = 10 # Second Example
while var > 0:
print 'Current variable value :', var
var = var -1
if var == 5:
break
print "Good bye!"
|
上面的代码都好理解,将这段代码保存在test_break.py文件中,运行结果如下:
[email protected]:~/Pytest/ch7$ python test_break.py
Current Letter : P
Current Letter : y
Current Letter : t
Current variable value : 10
Current variable value : 9
Current variable value : 8
Current variable value : 7
Current variable value : 6
Good bye!
[email protected]:~/Pytest/ch7$
|
continue语句与break不同,break是将整个循环结构给终止掉,而continue语句则只会将当次的循环体代码块给结束掉,然后会跳转到循环语句的开头,重新判断条件表达式(如果是for语句则从集合中迭代出下一个成员),当判断通过时(或者迭代出了下一个成员时),再继续执行下一次的循环体代码块。例如下面的例子:
for letter in 'Python':
if letter == 'h':
continue
print 'Current Letter :', letter
|
当for从'Python'字符串中将字符'h'提取到letter变量中时,
if letter ==
'h' 语句就会判断通过,此时就会去执行continue语句,该语句会跳转到for语句的开头(continue之后的print语句就不会被执行),并迭代出下一个'o'字符,再接着继续执行for下面的代码块。
continue语句的完整例子,如下所示:
#test_continue.py
for letter in 'Python': # First Example
if letter == 'h':
continue
print 'Current Letter :', letter
var = 10 # Second Example
while var > 0:
var = var -1
if var == 5:
continue
print 'Current variable value :', var
print "Good bye!"
|
上面例子中,当letter为'h'时,由于会执行continue语句,因此,'h'相关的print语句不会被执行。同理,上面的while循环结构中,当var为5时,在continue的作用下,对应的print语句也不会被执行。将以上代码保存到test_continue.py文件中,运行结果如下:
[email protected]:~/Pytest/ch7$ python test_continue.py
Current Letter : P
Current Letter : y
Current Letter : t
Current Letter : o
Current Letter : n
Current variable value : 9
Current variable value : 8
Current variable value : 7
Current variable value : 6
Current variable value : 4
Current variable value : 3
Current variable value : 2
Current variable value : 1
Current variable value : 0
Good bye!
[email protected]:~/Pytest/ch7$
|
可以看到,'h'和'5'都没显示出来,其他的字符与数字则不受影响,和预期的一致。
pass语句其实就是一个空语句,例如,在C语言中,我们可以编写如下所示的代码:
int var = 1;
if(var == 1)
;
else
printf("invalid var\n");
|
我们可以在if下面使用单一的分号来表示空语句,也就是当var为1时什么也不做,要在python中实现类似上面C代码的功能的话,就可以使用pass语句:
var = 1
if var == 1:
pass
else:
print 'invalid var'
|
因此,pass其实就是空语句的意思,如果上面代码中缺少pass语句的话,或者将pass变为单一的分号的话,都会产生语法错误(python中不能像C语言那样使用单一的分号来表示空语句),所以,pass在这种场合中,是不可缺少的。
模拟do...while语句:
在C语言中有do...while结构,在python中则没有该循环结构,要在python中实现该结构,只有通过while语句来实现,例如下面的C代码:
do {
stuff();
} while (condition());
|
do...while结构,其实就是将用于判断的条件表达式放在了最后,因此,该循环结构里的代码块,如上面的stuff()部分至少会被执行一次。在python中可以用while来模拟:
while True:
stuff()
if not condition():
break
|
上面将while的表达式设为True,这样stuff()至少会被执行一次,并将真正的condition()条件表达式放在最后,通过if语句来进行判断,当条件表达式返回False时,就通过break语句来结束循环,这样就模拟出do...while结构了。
以上就是本章的相关内容。
OK,休息,休息一下 o(∩_∩)o~~
健康的身体是灵魂的客厅,有病的身体则是灵魂的禁闭室。
—— 培根