5.3 循环(Loop)
for 循环
我们先来看一个例子,输入代码:
for every_letter in 'Hello world':
print(every_letter)
得到这样的结果:
H
e
l
l
o
w
o
r
l
d
这两行代码展示的是:用 for 循环打印出 “hello world” 这段字符串中的每一个字符。for 循环作为编程语言中最强力的特性之一,能够帮助我们做很多重复性的事情,比如批量命名、批量操作等等。
把 for 循环所做的事情概括成一句话就是:于…其中的每一个元素,做…事情。

for 是关键词,而后面紧接着的是一个可以容纳“每一个元素”的变量名称,至于变量起什么名字自己定,但切记不要和关键词重名。
在关键词 in 后面所对应的一定是具有“可迭代的”(iterable)或者说是像列表那样的集合形态的对象,即可以连续地提供其中的每一个元素的对象。
为了更深入了解 for 循环,试着思考以下问题,如何打印出这样的结果?
1 + 1 = 2
2 + 1 = 3
.
.
10 + 1 = 11
这需要用到一个内置函数一一range。我们只需要在 range 函数后面的括号中填上数字,就可以得到一个具有连续整数的序列,输入代码:
for num in range(1,11): #不包含11,因此实际范围是1~10
print(str(num) + ' + 1 =',num + 1)
这段代码表达的是:将 1~10 范围内的每一个数字依次装入变量 num 中,每次展示一个 num +1 的结果。在这个过程中,变量 num 被循环赋值10次,你可以理解成等同于:
num = 1
print(str(num) + ' + 1 =',num + 1)
num = 2
print(str(num) + ' + 1 =',num + 1)
.
.
num = 10
print(str(num) + ' + 1 =',num + 1)
现在我们试着解决更复杂的问题,把 for 和 if 结合起来使用。实现这样一个程序:歌曲列表中有三首歌“Holy Diver, Thunderstruck, Rebel Rebel”,当播放到每首时,分别显示对应的歌手名字“Dio, AC/CD, David Bowie”。
代码如下:
songslist = ['Holy Diver', 'Thunderstruck', 'Rebel Rebel']
for song in songslist:
if song == 'Holy Diver':
print(song,' - Dio')
elif song == 'Thunderstruck':
print(song,' - AC/DC')
elif song == 'Rebel Rebel':
print(song,' - David Bowie')
在上述代码中,将 songslist 列表中的每一个元素依次取出来,并分别与三个条件做比较,如果成立则输出相应的内容。
嵌套循环
在编程中还有一种常见的循环,被称之为嵌套循环(Nested Loop),其实这种循环并不复杂而且还非常实用。我们都学过乘法口诀表,又称“九九表”。

接下来我们就用嵌套循环实现它:
for i in range(1,10):
for j in range(1,10):
print('{} X {} = {}'.format(i,j,i*j))
正如代码所示,这就是嵌套循环。通过观察,我们不难发现这个嵌套循环的原理:最外层的循环依次将数值 1~9 存储到变量 i 中,变量 i 每取一次值,内层循环就要依次将 1~9 中存储在变量 j 中,最后展示当前的 i、j 与 i*j 的结果。如果忘了 {} 的用法,可以往回翻第三章最后一页看看。
While 循环
Python 中有两种循环,第一种 for 循环我们已经介绍过了,第二种则是 while 循环。它们的相同点在于都能循环做一件重复的事情,不同点在于 for 循环会在可迭代的序列被穷尽的时候停止,while 则是在条件不成立的时候停止,因此 while 的作用概括成一句话就是:只要…条件成立,就一直做…。

看一个简单的例子:
while 1 < 3:
print('1 is smaller than 3')
在这里先行提醒一下,一定要记得及时停止运行代码!

注:在终端或者命令行中搜 Ctrl + C 停止运行,在 PyCharm 中则点击红色的X停止。
因为在 while 后面的表达式是永远成立的,所以 print 会一直进行下去直至你的 cpu 过热。这种条件永远为 True 的循环,我们称之为死循环(Infinite Loop)。
但如果 while 循环不像 for 循环那样,在集合被穷尽之后停下来,我们怎样才能控制 while 循环呢?其中一种方式就是:在循环过程中制造某种可以使循环停下来的条件,例如:
count = 0
while True:
print('Repeat this line !')
count = count + 1
if count == 5:
break
在上面这段代码中,有两个重要的地方,首先是我们给一个叫 count 的变量赋值为 0,其目的是计数。我们希望在循环次数为 5 的时候停下来。接下来的是 break ,同样作为关键词写在 if 下面的作用就是告诉程序在上面条件成立的时候停下来,仅此而已。
然而你也一定发现了什么奇怪的地方,没错,就是这个 count = count + 1 !其实我已经不止一次强调过编程代码和数学公式在某些地方很相似,但又不完全相同,而这又是一个绝好的例子。首先在 Python 中 “=” 并非是我们熟知的“等于”的含义,所以我们不必按照数学公式一样把重复的变量划掉。其次 count 被赋值为 0,count = count +1 意味着 count 被重新赋值!等价于 count = 0 + 1,随着每次循环往复,count 都会在上一次的基础上重新赋值,都会增加1,直至 count 等于5 的时候break,跳出最近的一层循环,从而停下来。
利用循环增加变量其实还是一个挺常见的技巧,随着循环不仅可以增加,还可以随着循环减少(n = n - 1),甚至是成倍数增加 ( n = n * 3 )。
除此之外,让 while 循环停下来的另外一种方法是:改变使循环成立的条件。为了解释这个例子,我们在前面登录函数的基础上来实现,给登录函数增加一个新功能:输入密码错误超过3次就禁止再次输入密码。你可以尝试写一下,答案在下面揭晓。
password_list = ['##','12345']
def account_login():
tries = 3
while tries > 0:
password = input('Password:')
password_correct = password == password_list[-1]
password_reset = password == password_list[0]
if password_correct:
print('Login success!')
elif password_reset:
new_password = input('Enter a new password :')
password_list.append(new_password)
print('Password has changed successfully!')
account_login()
else:
print('Wrong password or invalid input!')
tries = tries - 1
print( tries, 'times left')
else:
print('Your account has been suspended')
account_login()
这段代码只有三处与前面的不一样:
- 第4~5行:增加了 while 循环,如果 tries >0 这个条件成立,那么便可输入密码,从而执行辨别密码是否正确的逻辑判断;
- 第20~21行:当密码输入错误时,可尝试的次数 tries 减少 1;
- 第23~24行:while 循环的条件不成立时,就意味着尝试次数用光,通告用户账户被锁。
在这里 while 可以理解成是 if 循环版,可以使用 while-else 结构,而在 while代码块中又存在着第二层的逻辑判断,这其实构成了嵌套逻辑(Nested Condition)。
练习题
一、设计这样一个函数,在桌面的文件夹上创建10个文本,以数字给它们命名。

二、复利是一件神奇的事情,正如富兰克林所说:“复利是能够将所有铅块变成金块的石头”。设计一个复利计算函数 invest(),它包含三个参数:amount(资金),rate(利率),time(投资时间)。输入每个参数后调用函数,应该返回每一年的资金总额。它看起来就应该像这样(假设利率为5%):

三、打印1~100内的偶数
建议你动手练习一次,然后在微信公众号中回复 循环 获得答案,微信公众号是:easypython

