上节回顾
上节中,我们理解了什么是 循环,学会用循环让计算机处理一系列重复的任务,并且走入海绵宝宝的世界,运用掌握的第一种循环结构——while
循环,帮他从繁琐的工作中解放出来。
你还记得 while
循环的结构吗?
今天我们就来学习一下:循环 “魔法”家族的另一个重要成员——for
循环。
for 循环
使用 while
循环后,海绵宝宝每天很快就能完成任务。蟹老板一看,大手一挥,决定增加订餐服务。比基尼海滩居民们纷纷响应,订餐时留下了自己的名字。
面对长长的订餐名单,海绵宝宝活学活用,写下了这样的程序:
# 预定蟹黄堡的客人名单
names = ['章鱼哥', '派大星', '泡芙老师', '珊迪']
# 定义变量 i,用来表示索引,初始值为 0
i = 0
# 使用 len() 函数获取列表 names 长度
num = len(names)
while i < num:
print('为客人' + names[i] + '做一份蟹黄堡')
# i 值加 1,为下一位客人制作蟹黄堡
i = i + 1
'''
输出:
为章鱼哥做一份蟹黄堡
为派大星做一份蟹黄堡
为泡芙老师做一份蟹黄堡
为珊迪做一份蟹黄堡
'''
使用 while
循环处理这种任务,要设置一个变量 i
表示索引,每次循环时,通过索引访问列表 names
中元素,还要给 i
加 1,从而访问到下一个元素,似乎还是有点麻烦。
我们先来看一下 for
循环的结构。
又见到了老朋友缩进和 循环体,相信聪明的你已经触类旁通:循环体是一段需要重复执行的代码,前面有 缩进,表示它受循环的管辖。
😵 然而 for
循环结构里没有循环条件,Python 是怎么知道自己什么时候该执行循环体的呢?
这也是 for
循环和 while
循环最大的区别。Python 中的 for
循环是通过 for ... in ...
语句实现循环的,强调的是对什么 序列 做重复操作。
计算机一遇到 for
,便会 依次 访问序列中的元素,赋值给变量 i
,执行一次循环体。当序列中的元素都访问完一遍,循环自然而然也就停止啦。而这种沿着某条路线,依次对序列中每个元素均做 一次 访问的过程,就叫做 遍历
。
我们来看看 for
循环的执行过程,加深一下理解吧。
for i in [1, 1, 2, 3]:
print(i)
# 逐行输出:1 1 2 3
# names 保存了几个人的名字
names = ['章鱼哥', '派大星', '泡芙老师', '珊迪']
for name in names:
print(name)
# 逐行输出:章鱼哥 派大星 泡芙老师 珊迪
for循环——编程练习
请你使用 for
循环完成任务,对每位客人都打印一行 为xxx制作一份蟹黄堡 吧(xxx 表示具体名字)。
main.py
# 预定蟹黄堡的客人名单
clients = ['章鱼哥', '派大星', '泡芙老师', '珊迪']
# 使用 for 循环,遍历列表 clients
# 预定蟹黄堡的客人名单
clients = ['章鱼哥', '派大星', '泡芙老师', '珊迪']
# 使用 for 循环,遍历列表 clients
for client in clients:
print('为' + client + '制作一份蟹黄堡')
对比一下课程开头海绵宝宝用 while
循环写的代码,用 for
循环来处理序列,是不是要简单很多?
除了 列表
类型,Python 中还有很多种序列,让我们一起来看看在 Python 中都有哪些常见的序列,又该如何遍历它们吧。
序列
在 Python 中,序列
指的是 有序 元素的集合。我们能使用 len()
函数获取它的长度,也能够用 索引 获取指定位置的元素。
看到长度、索引,你想到了什么?
没错~我们在列表单元学习的 列表
和 元组
,还有最开始接触的 字符串
,都是 Python 中很常用的序列。而 整数
、浮点数
和 布尔值
,它们都是一个个孤立的存在,自然也就不是序列了。
元组与字符串
遍历元组和遍历列表很相似,Python 会从元组第一个元素开始,依次访问到最后一个元素。
# 蟹黄堡配方
materials = (
'芝麻面包',
'煎肉饼',
'番茄酱',
'水母酱',
'芝士片',
'生菜',
'满满的爱'
)
# 遍历元组 materials
for material in materials:
print(material)
# 逐行输出:芝麻面包 煎肉饼 番茄酱 黄芥末酱 水母酱 芝士片 洋葱片 生菜 满满的爱
遍历 字符串
时,Python 则会从左往右依次访问字符串里的字符。
slogan = '我爱吃蟹黄堡'
for letter in slogan:
print(letter)
# 逐行输出:我 爱 吃 蟹 黄 堡
range()
通过之前的学习我们知道,range()
函数生成的是一串数字序列,可以使用 list()
函数,把它的返回值转换成列表再使用。其实,range()
函数的返回值可以直接索引,也能通过 len()
函数获取长度,是不折不扣的 序列。
所以想逐行输出 0、1、2 的话,我们不仅可以写成:
for i in [0, 1, 2]:
print(i)
# 逐行输出:0 1 2
还可以直接遍历 range(3)
,写成:
for i in range(3):
print(i)
# 逐行输出:0 1 2
学习的功夫,蟹堡王方向突然传来一阵骚动。原来是等待蟹黄堡的客人在店门口排起了长龙,队中有两人就位置问题起了争执。蟹老板重新整队后,思索了一下,打算给客人们发放号码牌。
序列——编程练习
下面请你使用 for
循环和 range()
函数,给正在等待的 10 名客人发放号码牌吧。
要求:为每位客人打印一张号码牌,格式为 x号(x 为具体数字,从 1 到 10)。
for i in range(10):
print(str(i + 1) + '号')
# 1号
# 2号
# 3号
# 4号
# 5号
# 6号
# 7号
# 8号
# 9号
# 10号
能转换成序列的数据
刚松了一口气,等待的客人又表示,只有一个号码还是容易搞混,希望可以加上自己的名字,以防有人冒充。一边是号码牌,一边是长长的名单,该怎样将这两个列表结合起来呢?
zip()
海绵宝宝沉思片刻,想到了在 大观园的欢乐日常 一关中学过的 zip()
函数,它刚好可以把两个列表打包组合起来,就像这样:
# 客人编号
ids = [1, 2, 3]
# 客人名字
names = ['派大星', '章鱼哥', '珊迪']
names_with_id = list(zip(ids, names))
print(names_with_id)
# 输出:[(1, '派大星'), (2, '章鱼哥'), (3, '珊迪')]
仔细观察一下不难发现,打包后的结果 names_with_id
实际上按顺序保存一个个形如 (编号, 名字)
的 元组
。对此 for
循环表示,像这样 能转换成序列 的结构,自己可以直接遍历,不用麻烦 list()
老哥费劲转换了。
🤔️ 不过这种结构在遍历时应该怎样访问其中的元素呢?在这里为你拓展一个知识点,对于保存着第一位客人信息的元组 info
,我们可以这样分别取到第一个、第二个元素。
# 第一位客人的信息
info = (1, '派大星')
id, name = info
print(id)
# 输出:1
print(name)
# 输出:派大星
这是 Python 中的特殊规则哦:用逗号 ,
分隔开的多个变量,可以 按顺序 一次性获取 序列 中的元素。需要注意的是,序列里有几个元素,就要用多少个变量把它们一一取出来。
比如海绵宝宝向元组 info
里又添加了一条信息。现在 info
里有三个元素,所以要用三个变量分别取出来。
# 第一位客人的信息
info = (1, '派大星', '石头屋')
id, name, address = info
# 这里就不能写成 id, name = info 啦
print('编号:' + str(id))
print('姓名:' + name)
print('住址:' + address)
'''
输出:
编号:1
姓名:派大星
住址:石头屋
'''
所以对于按编号、名字顺序组合起来的数据 zip(ids, names)
,我们可以设置 id
和 name
这两个变量去遍历它,就像这样:
# 客人编号
ids = [1, 2, 3]
# 客人名字
names = ['派大星', '章鱼哥', '珊迪']
# 遍历按编号、名字顺序组合起来的数据
for id, name in zip(ids, names):
print(str(id) + '号:' + name)
'''
输出:
1号:派大星
2号:章鱼哥
3号:珊迪
'''
zip()——编程练习
蟹老板看了上面的操作,打算把订餐服务也升级一下,让客人们留下名字和住址。
下面请你用 for
循环,对每位订餐的客人都打印出一行 为住在xxx的xxx送去蟹黄堡 吧。
# 客人住址
addresses = ['石头屋', '复活岛人像屋', '圆顶树屋']
# 客人名字
names = ['派大星', '章鱼哥', '珊迪']
zip = zip(addresses, names)
# 遍历按住址、名字组合起来的数据
for addre,name in zip:
# 或者可以将数据转为list
# for addre,name in list(zip):
print('为住在' + addre + '的' + name + '送去蟹黄堡')
enumerate()
给客人派号的任务,还可以拜托 enumerate()
函数来帮忙。它能给列表中每个元素都标上序号,并返回打包后的结果。
# 指定序号从 1 开始
names_with_id = list(enumerate(names, 1))
print(names_with_id)
# 输出:[(1, '派大星'), (2, '章鱼哥'), (3, '珊迪')]
它的返回值也是一个个元组呢,是不是跟 zip()
函数的返回值很像?我想聪明的你已经知道该怎么遍历了,让我们来验证一下:
# 等待就餐的客人列表
names = ['派大星', '章鱼哥', '珊迪']
# 遍历按序号、名字组合起来的数据
for id, name in enumerate(names, 1):
print(str(id) + '号:' + name)
'''
输出:
1号:派大星
2号:章鱼哥
3号:珊迪
'''
你看,编程是很灵活的,很多时候并非只有唯一解。只要能实现目标,代码怎么写都可以。相信在一次次练习中,你会慢慢总结出一些编写代码的心得,在解决问题的基础上,想到更高效的解法。到时候欢迎你跟老师分享哦 😉。
enumerate()编程练习
下面请你运用 enumerate()
函数,为列表 names
中的每位客人都打印出如下形式的号码牌吧。
注意:号码牌开始、结束的分割线已经保存在变量
line
里。打印号码牌时,序号从1
开始。
输出结果应为:
------------
序号:1
客人:派大星
------------
# 客人名字
names = ['派大星', '章鱼哥', '珊迪']
# 号码牌分割线
line = '------------'
# 为每位客人打印号码牌
编辑后:
# 客人名字
names = ['派大星', '章鱼哥', '珊迪']
# 号码牌分割线
line = '------------'
enumers = enumerate(names, 1)
# 为每位客人打印号码牌
for id,name in enumers:
print(line)
print('序号:' + str(id))
print('客人:' + name)
print(line)
循环体
循环体
内的代码,就是每次被重复执行的部分。因为这部分代码是受 for
循环管辖的,所以和我们之前学习的条件语句一样,每行前都有缩进,也就是两个空格。
把握好缩进,我们可以在循环体里实现更复杂的判断、数据处理。比如下面的例子,打印出了数字 1~10 中所有能被 3 整除的数字。
提示:运算符
%
是取余运算,比如5 % 2
表示 5 除以 2 的余数,结果为 1。
for i in range(1, 11):
# 除以 3 余数为 0,表示能被整除
if i % 3 == 0:
print(i)
# 逐行输出:3 6 9
除了条件结构,循环体里也可以嵌套新的循环。这种嵌套结构也叫做 双重循环。
比如说下面这个列表 customers
,它保存着在蟹堡王预订食物的顾客信息。其中每一位顾客的信息,都是形如 (姓名, 住址, 预订菜品)
的元组。
顾客信息表
customers = [
# 按“姓名、住址、所预订的食物”顺序,保存一名顾客信息
('派大星', '石头屋', '蟹黄堡', '香炸珊瑚'),
('章鱼哥', '人像屋', '蟹黄堡', '美味热狗'),
('珊迪', '树屋', '蟹黄堡')
]
可以看到,这几个元组是 不等长 的,派大星和章鱼哥都预订了两样食物,珊迪只预订了一样。这样的数据要怎么遍历呢?先来看看老师写好的示例吧。
编程练习一
看看如何打印出列表 customers
中所有信息。
# 顾客信息表
customers = [
# 按“姓名、住址、所预订的食物”顺序,保存一名顾客信息
('派大星', '石头屋', '蟹黄堡', '香炸珊瑚'),
('章鱼哥', '人像屋', '蟹黄堡', '美味热狗'),
('珊迪', '树屋', '蟹黄堡')
]
# 外层循环,遍历每位顾客
for customer in customers:
# 内层循环,遍历顾客的每个信息
for info in customer:
# 打印该信息
print(info)
# 遍历完一名顾客信息后,打印一条分割线
print('---------')
'''输出结果为'''
# 派大星
# 石头屋
# 蟹黄堡
# 香炸珊瑚
# ---------
# 章鱼哥
# 人像屋
# 蟹黄堡
# 美味热狗
# ---------
# 珊迪
# 树屋
# 蟹黄堡
# ---------
Python 是怎么打印出这些内容的呢?我们来玩一个假扮机器人的游戏,把自己代入计算机的角色,看看程序是如何运行的吧:
计算机执行到第 10 行,看到 for ... in ...
语句,明白了自己需要遍历 customers
这个列表,于是开始依次访问其中元素。每次访问时,都把取出来的元素赋值给变量 customer
,执行一遍外层循环的循环体,也就是第 11~16 行。
而在外层循环的循环体里,又有一个 for
循环。所以计算机会先遍历 customer
元组,每次访问时,都把取出来的元素赋值给变量 info
,执行一遍内层循环的循环体,也就是第 14 行。等遍历完成,再继续执行外层循环的循环体剩余内容。
在今天的课程中,我们解锁了另一个 Python 中处理重复劳动的循环结构——for
循环。
从形式上看,for
循环通过 for ... in ...
语句告诉计算机开始循环,具有循环体;从功能上说,for
循环依次遍历序列中元素,赋值给变量,并执行一次循环体内代码。
for
循环能遍历的对象可多啦,对照着下图回忆一下吧。
循环“魔法”的两员大将都已经解锁,各位初级魔法师是不是运用得游刃有余呢?
编程练习二_小蝌蚪找妈妈
小蝌蚪找妈妈的故事你小时候一定听过,接下来我们用 for
循环的知识编写小蝌蚪找妈妈的故事。
animals = ['鸭', '鱼', '乌龟', '鹅', '虾', '青蛙']
要求:
- 使用
for
循环遍历列表animals
; - 每次循环都在屏幕上打印 请问你是我妈妈吗?;
- 当遇到 青蛙 时打印 青蛙:我是你妈妈,遇到其他动物时则打印 xxx:我不是你妈妈(xxx 为具体动物名)。
animals = ['鸭', '鱼', '乌龟', '鹅', '虾', '青蛙']
# 遍历 animals 列表,完成上述任务
for animal in animals:
print('请问你是我妈妈吗?')
if '青蛙' == animal:
print('青蛙:我是你妈妈')
else:
print(animal + '我不是你妈妈')
print('太好了,我终于找到妈妈了!')
编程练习三_100 以内的奇数和
上一关我们已经知道了 100 以内所有数的和为 5050,那么奇数和会是多少呢?请你补全 counting()
函数完成这个计算,打印出 100 以内(包括100)所有奇数的和。
def counting(n):
# 请补全代码
counting(100)
答案为:
# 当然不止这一种答案
def counting(n):
# 请补全代码
sum = 0
# 从1开始,到101结束(不包含101),每次+2::1,3,5 ...99
for i in range(1, n + 1, 2):
if i % 2 == 1:
sum += i
print(sum)
counting(100)
编程练习四_停车检查
交警叔叔已经工作了一天了,他想知道有多少大卡车通过当前路段。今天通过的车辆种类都存在列表 cars
中,请你用 for
循环帮助交警叔叔进行统计,打印出 今天有n辆大卡车通过,其中 n 为大卡车的数量。
cars = ['小汽车', '大卡车', '警车', '小汽车', '救护车', '救护车', '大卡车', '警车', '小汽车', '救护车', '大卡车', '公交车', '小汽车', '救护车', '大卡车', '警车', '小汽车', '救护车', '大卡车', '大卡车', '警车', '小汽车', '救护车']
def truck():
# 请补全代码
print('今天有' + ??? + '辆大卡车通过')
truck(cars)
cars = ['小汽车', '大卡车', '警车', '小汽车', '救护车', '救护车', '大卡车', '警车', '小汽车', '救护车', '大卡车', '公交车', '小汽车', '救护车', '大卡车', '警车', '小汽车', '救护车', '大卡车', '大卡车', '警车', '小汽车', '救护车']
def truck(cars):
# 定义初始数量
sum = 0
# 遍历列表
for car in cars:
if '大卡车' == car:
sum += 1
print('今天有' + str(sum) + '辆大卡车通过')
truck(cars)
编程练习五_九九乘法表
1x1=1
---------
2x1=2
2x2=4
---------
3x1=3
3x2=6
3x3=9
---------
4x1=4
4x2=8
4x3=12
4x4=16
---------
......
要求:
- 乘法表共有 9 组算式,第一组有 1 个算式,第二组有 2 个,以此类推;
- 每个算式中,总是较大的乘数在前,较小的乘数在后。
提示:假设两个乘数为
i
和j
,那么一个算式可以用str(i) + 'x' + str(j) + '=' + str(i * j)
字符串表示。
for i in range(1,10):
for j in range(1,i + 1):
print(str(i) + 'x' + str(j) + '=' + str(i * j))
print('---------')
下一篇:python循环中的 break
和 continue
语句