抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

image-20210421205433759

第五章 列表:遍历

遍历整个列表

为何需要循环

任务:为何需要循环?

假设有一个班级名单(列表),需要将其中每个同学名字都打印出来,并对他/她说一句问候语。按之前学到的Python知识,可以分别地(依次)获取名单中的每个名字,但这种做法会导致多个问题:

  • 如果名单很长,为每个人写问候语,将包含大量重复的代码
  • 列表可以动态增减,每当名单的长度发生变化时,都必须对代码进行增减,不易维护。
  • 重复性的工作。

为解决上述问题,需要使用循环技术。

循环让我们可以对列表的每个元素都采取一系列相同(重复性)的操作,从而高效地处理任何长度的列表,包括包含数千乃至数百万个元素的列表。

任务:掌握for循环语法

知识点:

  • 遍历就是从头到尾依次列表中获取数据(元素),然后在循环体内部每个元素执行相同操作
  • 为实现遍历,Python引入for循环(for-each)机制。
  • 为了提高列表的遍历效率,Python专门提供了迭代器iteration来实现遍历功能。关于迭代器后续会讲解,这里仅作了解。

知识点:for循环语法。

  • 描述: for循环用于迭代/遍历序列对象(即列表,元组,字典或字符串)。通过使用for循环,可以对序列中的每个元素执行一系列重复的语句/操作。

  • 语法:

    1
    2
    3
    4
    5
    for item in sequence:
    statements(item)

    for 临时变量 in 序列对象(比如列表):
    循环体语句块(必须相同的缩进)

知识点(术语):何谓迭代

  • 迭代:每运行一次循环体statements,称迭代一次
  • 迭代次数:循环共运行了几次。
  • 迭代条件:满足循环的条件。

任务:列表的应用场合分析

知识点:

  • 尽管 Python 列表中可以存储不同类型的数据

  • 但是在开发中,更多的应用场景是

    1. 列表存储相同类型的数据。
    2. 通过迭代遍历,在循环体内部,针对列表中的每一项元素,执行相同的操作。

深入列表for循环

任务:for循环的注意事项

for循环注意事项:

  • 在循环体语句块中,执行重复代码。
  • C++或Java使用{ }来管理语句块,所以他们对缩进不敏感。
  • Python敏感于代码缩进。它通过代码缩进,来管理和识别语句块。
  • 同个语句块代码需要采用相同的缩进量,如果不恰当的使用缩进,将会报错。
  • 请善用代码排版插件小锤子。
  • 这种遍历适用于任何序列对象(不局限于列表)。

任务:循环通过缩进标识循环体

在程序设计中,循环是一项非常重要的技术,因为它可以让计算机自动完成重复工作。

知识点

  • 循环意义:在每次迭代过程中,依次从列表numbers中取出元素,并赋值给临时变量(局部)val,然后再对每个val执行相应的操作。

  • Python循环语法:循环体通过缩进被Python解释器识别。

    • 循环体的前后,多敲一个回车空行
    • 通过循环体内与循环体外的相对缩进,来标识循环语句块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
print('----求解列表元素之和----')
numbers = [6, 5, 3, 8, 4, 2, 5, 4, 11]
sum = 0

# 循环前后多敲空格
for val in numbers:
sum = sum + val

# 循环体之外语句不缩进
print("The sum is", sum)


#----求解列表元素之和----
#The sum is 48

任务:for循环的临时变量为局部变量

知识点:

  • 在循环体中,对循环体内的局部变量进行修改,不会影响原列表的元素值
  • 例如,for val in numbers:val进行修改,不影响numbers的值。
  • val是局部变量,作用域只限制于循环体。
1
2
3
4
5
6
7
8
9
10
11
numbers = [6, 5, 3, 8, 4, 2, 5, 4, 11]
print('循环前:', numbers)

#val为局部变量
for val in numbers:
val = val + 1

print('循环后:', numbers)

#循环前: [6, 5, 3, 8, 4, 2, 5, 4, 11]
#循环后: [6, 5, 3, 8, 4, 2, 5, 4, 11]

任务:通过临时变量实现批量运算

知识点:

  • 循环的目的是对一组数据实现批量重复性操作
  • 在循环体内,通过对局部变量进行运算和操作,对列表元素实现批量地重复性操作
1
2
3
4
5
6
7
8
9
10
11
12
names = ['alice', 'david', 'carolina']

# 通过临时变量name实现对列表元素批量操作
for name in names:
print('Hello, ' + name.title() + '!')

print('打印结束!')

#Hello, Alice!
#Hello, David!
#Hello, Carolina!
#打印结束!

代码解析

  • 首先,定义了一个列表。
  • 接下来,定义一个for循环;这行代码让Python从列表names中取出一个名字,并将其存储在变量name中。
  • 最后,让Python打印前面存储到变量name中的名字。这样,对于列表中的每个名字,Python都将重复执行循环体代码。

习题

第一题

题目要求:

  • 创建字符串”hello, python”,遍历打印每个字符。

代码如下:

1
2
3
massage="hello,python"
for val in massage:
print(val,end=' ')

运行结果:

1
h e l l o , p y t h o n 

第二题

题目要求:

  • 输入一个水果的列表,遍历打印每种水果。

代码如下:

1
2
3
FruitsList=["apple","banana","pear"]
for val in FruitsList:
print(val)

运行结果:

1
2
3
apple
banana
pear

for循环体包含多条语句

任务:for循环体使用多条语句

之前的循环体都是一行代码,在本节将循环体扩展为多行。在for循环中,可对每个元素执行任何操作。

知识点:

  • Python解释器使用缩进来判断循环体语句块的范围。
  • for的声明之后到遇到第一个与for同级别缩进的语句。
  • 例如,在for name in names后面,每个缩进的代码行都是循环体部分,这部分的代码将针对列表中的元素都执行一次
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
names = ['alice', 'david', 'carolina']

for name in names:
# print()在输入末尾默认插入换行符。
print(name.upper() + ", that was a great trick!")

print(name.lower() + ", that was a great trick!")
# 换行符\n在每次迭代结束后都额外插入一个空行。
print("Thanks for your show, " + name.title() + ".\n")

print('循环之外') #与for同级别的缩进,循环之外的语句。

#-------输出--------
# ALICE, that was a great trick!
# alice, that was a great trick!
# Thanks for your show, Alice.

# DAVID, that was a great trick!
# david, that was a great trick!
# Thanks for your show, David.

# CAROLINA, that was a great trick!
# carolina, that was a great trick!
# Thanks for your show, Carolina.

# 循环之外

for循环结束的标志(易错)

任务:for循环结束标志

for循环结束后再怎么做呢?通常,需要提供总结性输出或接着执行程序必须完成的其他任务

知识点:与for同级别缩进的代码不属于循环体代码,它们只执行一次,而不会重复执行。

例子:首先在循环体为每个成员打印2条消息;然后,在循环结束之后,输出1条总结性的消息,需要将相应的代码放在与for同级别缩进处:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
names = ['alice', 'david', 'carolina']

for name in names:
# 两条print语句针对列表中每位成员重复执行
print(name.title() + ", that was a great trick!")
print("Thanks for your show, " + name.title() + ".\n")

# 第三条print语句没有缩进,因此只执行一次
print("Thank you, everyone. That was a great show!")

# ---- 输出 ----
# Alice, that was a great trick!
# Thanks for your show, Alice.

# David, that was a great trick!
# Thanks for your show, David.

# Carolina, that was a great trick!
# Thanks for your show, Carolina.

# Thank you, everyone. That was a great show!

任务:循环体通过缩进进行标识

知识点:多重循环,用缩进来识别每重for的循环体语句块范围。

1
2
3
4
5
6
7
numbers = [1,2,3,4]
sum = 0

for val1 in numbers: #外层循环
for val2 in numbers: #内层循环
print(val1*val2, end = ' ') #内循环语句
print('') #外循环语句

代码解析:

  • 两个嵌套的for循环。过程类似于C语言。

  • 外层循环体包括:整个内层循环+print('')

  • 程序步骤如下:

    • 首先,在外层循环取列表numbers第一个元素1赋值给val1
    • 然后,进入内层循环,依次取列表numbers赋值给val2。并执行内层循环体print(val1*val2, end = ' ')
    • 内层循环结束后,返回到外层循环,执行print('')
    • 此时,外层循环被完整地执行一次。Python再次检测外循环是否遍历完所有元素,如果否则再次执行循环。
  • print()中的end参数:在输出的结尾加入一个end字符,默认为换行符。end = ' '表示print()函数最后输出加``空格符。各位可以参数修改end参数,观察结果。

  • print(''):输出换行。因为end参数的默认值是换行符。输出空字符,则代表对当前输出进行换行。

习题

第三题

题目要求:

想出至少三种你喜欢的比萨,将其名称存储在一个列表中,再使用for循环将每种比萨的名称都打印出来。

  • 修改这个for循环,使其打印包含比萨名称的句子,而不仅仅是比萨的名称。对于每种比萨,都显示一行输出,如“I like pepperoni pizza”。
  • 在程序的循环结束后,添加一行代码,输出总结性的语句,如“I really love pizza!”。

代码如下:

1
2
3
4
5
6
7
8
PizzaList=["pepperoni","Chicago-Style","California-style","Bar"]
for val in PizzaList:
print(val)

for val in PizzaList:
print("I like "+val+" pizza")

print("I really love pizza!")

运行结果:

1
2
3
4
5
6
7
8
9
pepperoni
Chicago-Style
California-style
Bar
I like pepperoni pizza
I like Chicago-Style pizza
I like California-style pizza
I like Bar pizza
I really love pizza!

第四题

题目要求:

  • 想出至少三种有共同特征的动物,将这些动物的名称存储在一个列表中,再使用for循环将每种动物的名称都打印出来。
    • 修改这个程序,使其针对每种动物都打印一个句子,如“A dog would make a great pet”。
    • 在程序末尾添加一行代码,指出这些动物的共同之处,如打印诸如“Any of these animals would make a great pet!”这样的句子。

代码如下:

1
2
3
4
5
6
7
AnimalList=["dog","cat","bird"]
for val in AnimalList:
print(val)
for val in AnimalList:
print('A '+val+' would make g great')

print("Any of these animals would make a great pet!")

运行结果:

1
2
3
4
5
6
7
dog
cat
bird
A dog would make g great
A cat would make g great
A bird would make g great
Any of these animals would make a great pet!

常见的缩进错误

知识点:

  • Python根据缩进来判断代码行与前一个代码行的关系。

    • 比如for循环用缩进来识别语句块范围。
    • 同样适用于后的while循环、if判断、def函数和class类的定义等。
  • 正确的使用Python的缩进技术,非常重要。

  • Python通过使用缩进让代码更易读;简单地说,它要求你使用缩进让代码整洁而结构清晰

  • 通过代码不同程度的缩进,可以快速的掌握程序的组织结构。

任务:忘记缩进(错误)

知识点

  • 对于位于for语句:之后循环体代码,一定要缩进
  • 如果忘记缩进,Python解释器将会提示错误。
1
2
3
4
5
6
7
8
9
names = ['alice', 'david', 'carolina']
print('------for循环语句块必须要至少一行代码------')
for name in names:
print(name)

# File "<ipython-input-3-bec157200367>", line 4
# print(name)
# ^
# IndentationError: expected an indented block

任务:忘记缩进额外的代码行(错误)

知识点

  • 解释器只检测for语句头之后的第一句是否缩进。
  • 非第一句的循环体语句,Python无法检测,这将会发生逻辑错误代码可以运行,结果出乎意料
1
2
3
4
5
6
7
8
9
10
names = ['alice', 'david', 'carolina']
for name in names:
print(name.title() + ", that was a great trick!")
# 不检测for第一句之后的语句是否缩进
print("Thanks for your show, " + name.title() + ".\n")

# Alice, that was a great trick!
# David, that was a great trick!
# Carolina, that was a great trick!
# Thanks for your show, Carolina.

程序解析:

  • 第二条print语句原本需要缩进,但Python发现for语句后面有一行代码是缩进的,因此它没有报告错误。
  • 程序结果是,对于列表中的成员,都执行了第一条print语句,因为它缩进了;而第二条print语句没有缩进,因此它只在循环结束后执行一次。
  • 由于变量name的终值为'carolina',因此只有她收到了消息“Thanks for your show, Carolina.”。

任务:非语句块的不必要缩进(错误)

知识点

  • 非循环体(代码块)的代码不要缩进,否则将会发生语法或逻辑错误。

  • 代码块标志是什么?

    • 在冒号:之后,需要用缩进来标识代码块范围。
    • 代码块范围:冒号:之后代码 到 第一行与for同级别缩进的代码。
    • 为优雅的区分代码块代码,请在代码块结束后多加一个换行
1
2
3
4
5
6
7
8
message = "Hello Python world!"
print('------------不在代码块中的代码不允许缩进--------')
print(message) # 非语句块的缩进,将会发生错误

# File "<ipython-input-5-7b2c6f3f0548>", line 3
# print(message)
# ^
# IndentationError: unexpected indent

任务:同一级别的代码必须使用统一缩进

知识点同一级别代码的缩进规则

  • 允许:同一级别的代码必须要采用统一的缩进,不管缩进多少个空格。

  • 不允许:但Python不允许它们采用不同统一缩进

    • 建议第一级别的代码顶格写,之后凡是遇到语句块再依次缩进
    • 比如二重循环,第二层循环语句块需要缩进两个级别
1
2
3
4
5
6
   print("允许同一级别的代码都采用统一的缩进")
print("允许同一级别的代码都采用统一的缩进")

--------------------------------------------
允许同一级别的代码都采用统一的缩进
允许同一级别的代码都采用统一的缩进
1
2
3
4
5
6
7
8
 print("不允许同一级别的代码采用不同统一的缩进")
print("不允许同一级别的代码采用不同统一的缩进")

---------------------------------------------
File "<ipython-input-27-d5097ab6b28d>", line 2
print("允许同一级别的代码都采用统一的缩进")
^
IndentationError: unexpected indent

第一个代码块,代码虽然不顶格,但是同一级别采用相同缩进方式,所以代码可以正常运行;第二代码块,将会触发缩进错误。

任务:语句块之后不必要的缩进(错误)

知识点

  • 循环体语句块之后的代码,如果不恰当的使用了缩进,Python将会视它为语句块代码,将会发生语法错误或逻辑错误。
  • 有些缩进问题是语法错误,Python解释器会报错误,可通过报错代码,找到出错原因。
  • 但是很多缩进问题是逻辑错误,Python不会报逻辑错误,程序一般都能正常运行。因此,排查逻辑错误,通常需要花更多的时间。
  • Python的语句块缩进很容易造成初学者逻辑错误,因此一定要小心使用。

例子:不小心缩进了应在循环结束后执行的代码,这些代码将针对每个列表元素重复执行。

1
2
3
4
5
6
names = ['alice', 'david', 'carolina']
for name in names:
print(name.title() + ", that was a great trick!")
print("我是语句块代码,请缩进包括我吧!\n")

print("我不是语句块代码,请不要缩进包括我,否则将会发生逻辑错误!")

任务:遗漏冒号

知识点

  • 代码块的标志是什么?在冒号:之后,需要用缩进来标识代码块范围。

  • 如果遗漏了:,Python将无法判断哪里是语句块的开始,那么将会报错。

  • 这个错误是语法错误,相信Python肯定会报的。

1
2
3
4
5
6
7
8
names = ['alice', 'david', 'carolina']
for name in names
print(name)

# File "<ipython-input-6-2a56c4e8eee2>", line 2
# for name in names
# ^
# SyntaxError: invalid syntax

数值数列

任务:序列类型或容器类型

知识点:什么叫序列类型?

  • 序列是Python中最基本的数据结构,它是容器类型的数据类型。

  • 序列中的每个元素都分配了一个称为索引的整数(用于指明元素位置)。

    • 例如,第一个索引是0,第二个索引是1,依此类推。
  • Python有6个序列的内置类型,但最常见的是列表元组字符串

很多应用都会涉及到处理和储存一组数值类型的数据。例如,在游戏中,需要跟踪每个角色的位置信息,还可能需要对玩家进行积分排行。

知识点:

  • 类似于C语言中的数组,在Python中,可使用列表list来管理一组数值类型的数据。
  • 列表是一种Python序列类型(容器类型),它提供了很多便捷的方法来处理和维护数据(列表元素)。
  • 即使列表包含数百万个元素,也可以很高效的处理。

使用函数range()生成数值序列

任务:range()数值序列生成函数

知识点:

  • 语法:range(stop)range(start, stop[, step])

  • 描述:range()函数生成一个从start开始到stop(但不包括)按step步长的整形序列(非列表)。Python内置函数,一般用在for循环中。

  • 参数:

    • start: 从start开始。默认值为0。例如range(5)等价于range(0,5)
    • stop: 到stop结束,但不包括stop。例如:range(0,5)[0, 1, 2, 3, 4]不包括5。
    • step:步长,默认值为1。例如:range(0,5)等价于range(0,5,1)
  • 返回:一个range对象。而不是列表类型,所以调用print()时,不会直接打印序列元素。

  • 限制:只能生成整数序列。

1
2
3
4
5
num = range(1, 5, 1)
# print不会显示具体元素值
print(num, type(num))

#range(1, 5) <class 'range'>

任务:print()的end参数使用

知识点:

  • print()函数的参数end ='字符'指定print结束之处添加的’字符’。
  • end参数的默认值为换行符\n
1
2
3
4
5
6
7
for value in range(1, 5, 1):
print(value) #默认值为`\n`换行

# 1
# 2
# 3
# 4
1
2
3
4
for value in range(1, 5, 1):
print(value, end=' ') #修改end参数为空格

# 1 2 3 4
  • 注意,range()只生成了1~4,并非想象中的1~5
  • 函数range()让Python从startstop-1范围创建整数序列,不包括stop值。
  • 使用range()时,如果输出结果不符合预期,请尝试将对参数值进行加1或减1尝试。

任务:range()函数参数不能为空

知识点:

  • range()的3个参数只能为整形,不能为浮点数
  • 否则就会出错。
1
2
3
4
5
6
7
8
9
10
# 任意一个参数为浮点数会报错
num = range(1,1.5,5)

# ---------------------------------------------------------------------------
# TypeError Traceback (most recent call last)
# <ipython-input-9-1d19c399ee0c> in <module>
# 1 # 任意一个参数为浮点数会报错
# ----> 2 num = range(1,1.5,5)

# TypeError: 'float' object cannot be interpreted as an integer

任务:range()函数的等价形式

知识点:range(n) 等价于 range(0,n,1)

1
2
3
4
5
6
7
8
9
10
for value in range(6):
print(value, end=' ')

print('') # 换行

for value in range(0, 6,1):
print(value, end=' ')

# 0 1 2 3 4 5
# 0 1 2 3 4 5

知识点:

  • 为生成浮点数序列,可将range()生成的整数序列。
  • 然后,除以特定的数,得到等间隔的小数序列。
1
2
3
4
for value in range(1, 10, 2):
print(value/10, end=' ')

# 0.1 0.3 0.5 0.7 0.9

任务:通过遍历或索引获取range()序列元素

知识点:深入解析range()函数。

  • range()被创建时,在内存中不直接生成所有的序列元素
  • 元素只有在使用时,比如遍历或索引访问时,才会在内存中被生成。
  • 这种方式可以大大的降低程序对内存的使用。

通过索引循环来遍历来访问range()序列元素。

1
2
3
4
5
6
7
8
9
10
11
12
num = range(1,10, 2)

# 索引访问num[1],range(1,10, 2)生成相应的元素
# 其他元素由于没使用,所以不被生成
print(num[1])

# 使用循环遍历元素
for i in num:
print(i, end=' ')

# 3
# 1 3 5 7 9

任务:使用list()将range对象转换为列表

知识点:

  • 通过list()函数可以将range()对象的所有元素转换为列表。
  • 返回数值类型的列表。

习题

第六题

题目要求:

  • 计算1到100的整数之和,奇数之和,偶数之和。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ListNum=range(1,101,1)
Integer_Sum=0
for val in ListNum:
Integer_Sum=Integer_Sum+val

ListNum=range(1,101,2)
OddNumber_Sum=0
for val in ListNum:
OddNumber_Sum=OddNumber_Sum+val

ListNum=range(0,101,2)
EvenNumber_Sum=0
for val in ListNum:
EvenNumber_Sum=EvenNumber_Sum+val

print(Integer_Sum,OddNumber_Sum,EvenNumber_Sum)

运行结果:

1
5050 2500 2550

第七题

题目要求:

  • 输入两个整数ab,计算区间[a b]整数之和。

代码如下:

1
2
3
4
5
6
7
8
9
a=int(input())
b=int(input())
ListNum=range(a,b+1,1)
s=0
for val in ListNum:
s=s+val

print(s)
#a=1;b=9

运行结果:

1
2500

第八题

题目要求:

  • 输入两个数,求最大公约数和最小公倍数。提示:使用for循环,和range()

代码如下:

1
2
3
4
5
6
7
8
9
10
num1 = int(input('Num1:'))
num2 = int(input('Num2:'))
min_num = min(num1,num2)
for i in range(1,min_num + 1):
if num1 % i == 0 and num2 % i == 0:
gys = i
gbs = int((num1 * num2) / gys)
print('%s和%s的最大公约数为:%s' %(num1,num2,gys))
print('%s和%s的最小公倍数为:%s' %(num1,num2,gbs))
#num1=3;num2=27

运行结果:

1
2
3和27的最大公约数为:3
3和27的最小公倍数为:27

第九题

题目要求:

  • 生成一个列表,列表元素分别为[12,22,32…n2]。

代码如下:

1
2
3
4
5
6
n=int(input('项数'))
n=n+1
ListNum=range(12,10*n+2,10)
for val in ListNum:
print(val)
#n=4

运行结果:

1
2
3
4
12
22
32
42

第十题

题目要求:

  • 找出1~10之间所有偶数,返回一个列表,包含以这个偶数为半径的圆的面积。

代码如下:

1
2
3
4
pi=3.14
for r in range(2,11,2):
print(r,end=' ')
print(pi*r*r)

运行结果:

1
2
3
4
5
2 12.56
4 50.24
6 113.03999999999999
8 200.96
10 314.0

使用range()输出乘法表

任务:使用range()输出乘法表

知识点:

  • print()函数的参数 end ='字符'指定print结束之处添加’字符’。
  • 它的默认为换行符\n

使用双重循环,并通过print()语句输出乘法表。

1
2
3
4
5
6
7
8
9
10
for i in range(1, 4):
for j in range(1, 4):
print(i,'*', j,'=', i * j, end=" ")
print('') #换行

print('乘法表')
# 1 * 1 = 1 1 * 2 = 2 1 * 3 = 3
# 2 * 1 = 2 2 * 2 = 4 2 * 3 = 6
# 3 * 1 = 3 3 * 2 = 6 3 * 3 = 9
# 乘法表
  • 循环体的核心语句print(i,'*', j,'=', i * j, end=" "),输出每个乘法结果。
  • 这个print()语句为输出乘法算式结果,共用了6个字符串拼接,以,相隔。

上述的输出语句非常复杂,那么Python是否提供更好的解决方案?.format()字符串格式函数。

任务:.format()函数的乘法表

使用.format()函数来格式化输出乘法表。

1
2
3
4
5
6
7
8
9
10
11
12
for i in range(1, 4):
for j in range(1, 4):
# print(i,'*', j,'=', i * j, end=" ")
print("{}*{}={}".format(i,j,i*j), end=" ")
print('')

print('乘法表')

# 1*1=1 1*2=2 1*3=3
# 2*1=2 2*2=4 2*3=6
# 3*1=3 3*2=6 3*3=9
# 乘法表

使用list()转换数字列表

任务:使用list()将range对象转换为列表

知识点:

  • 由于range()数字序列生成器,不能直接在内存中生成数字列表,只有元素被使用时,才会生成数字。
  • 可以通过list()函数可以将range对象的所有元素转换为列表,返回数值类型的列表。
  • range()返回作为list()函数的参数:list(range(10))
  • list类型的数据,在内存中真实存在;range类型的数据,在内存中不存在(不占内存)。
1
2
3
4
5
6
7
8
9
# range()数字序列生成器,无论多大的数据都不占内存
print(range(1,6000000), type(range(1,6)))

# 通过list()将range对象转换为list
# list元素在内存中真实存在
num = list(range(1,6))
print(num, type(num))
# range(1, 6000000) <class 'range'>
# [1, 2, 3, 4, 5] <class 'list'>

使用函数range()时,还可指定step步长。

例如,下面的代码打印1~10内的偶数,函数range()start=2开始,然后不断地加step=2,直到达到或超过stop(11)。

1
2
3
even_numbers = list(range(2, 11, 2))
print(even_numbers)
# [2, 4, 6, 8, 10]

任务:两种生成平方数列表的方式

使用函数range()几乎能够创建任何需要的数字序列。

例如,创建一个包含前10个整数的平方数序列。在Python中,两个星号**表示乘方运算。下面的代码演示了如何将前10个整数的平方通过循环逐个加到squares列表中:

1
2
3
4
5
6
7
squares = []
for value in range(1, 11):
square = value**2
squares.append(square)

print(squares)
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

程序解析:

  • 首先,创建了一个空列表squares
  • 接下来,使用函数range()让Python遍历1~10的值。
  • 在循环中,计算当前值的平方,并将结果append()到变量square中。
  • 然后,将新计算得到的平方值附加到列表squares末尾。
  • 最后,循环结束后,打印列表squares

为让这些代码更简洁,在循环体中可不使用临时变量square,而是直接将每个平方结果附加到列表末尾:

1
2
3
4
5
6
squares = []
for value in range(1, 11):
squares.append(value**2)

print(squares)
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

创建更复杂的列表时,可使用上述的两种方法。

  • 作为新手,建议使用第1中方式,通过使用临时变量会让代码更易读。
  • 熟悉之后,可以使用第二种更简便的方式,降低代码冗余度。

统计列表的信息

任务:列表的信息统计

Python提供了几个专门用于处理列表元素的内建(build-in)函数,即python自带函数。

知识点:

  • min()方法返回列表元素中的最小值。
  • max()方法返回列表元素中的最大值。
  • sum()方法返回列表元素之和。
1
2
3
4
digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
print(min(digits)) # 0
print(max(digits)) # 9
print(sum(digits)) # 45

知识点:字符串列表的最小和最大值。

  • min()max()同样适合字符串列表。
  • 字符串列表的元素比较,先比第一位,如果相同,则再比第二位。以此类推。
1
2
list1 = ['113', '11111', '1122']
print(min(list1)) # 11111

习题

第十一题

题目要求:

  • 使用一个for循环打印数字1~20(包含)。

代码如下:

1
2
for num in range(1,21,1):
print(num,end=' ')

运行结果:

1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 

第十二题

题目要求:

  • 创建一个列表,其中包含数字1~1 000 000,再使用一个for循环将这些数字打印出来(如果输出的时间太长,按Ctrl + C停止输出,或关闭输出窗口)。

代码如下:

1
2
for num in range(1,1000000,1):
print(num,end=' ')

运行结果:

1
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 ......

第十三题

题目要求:

  • 创建一个列表,其中包含数字1~1 000 000,再使用min()max()核实该列表确实是从1开始,到1 000 000结束的。另外,对这个列表调用函数sum(),看看Python将一百万个数字相加需要多长时间。

代码如下:

1
2
3
4
List=range(1,1000001,1)
print(min(List))
print(max(List))
print(sum(List))

运行结果:

1
2
3
4
5
1
1000000
500000500000

[Done] exited with code=0 in 0.197 seconds

第十四题

题目要求:

  • 通过给函数range()指定第三个参数来创建一个列表,其中包含1~20的奇数;再使用一个for循环将这些数字都打印出来。

代码如下:

1
2
3
mylist=range(1,20,2)
for num in mylist:
print(num,end=' ')

运行结果:

1
1 3 5 7 9 11 13 15 17 19 

枚举:遍历列表的索引

认识可迭代对象

任务:可迭代对象

知识点:

  • 为何列表可以直接使用for-in语句来遍历元素?

    • 因为它是黑科技,可迭代对象
  • 列表可以直接遍历获得列表元素,而不像C++或Java是通过下标索引方式来遍历列表。

  • for循环并非只限于列表,任何可迭代对象都可使用此功能。

知识点:何谓可迭代对象?(只需要了解基本概念,不需要深入)

  • 可以被遍历的对象,任何可以用for-in语句来获取元素的对象都是可迭代对象。即,

    1
    2
    for iterating_var in sequence:
    statements(s)
  • 描述:可迭代对象每次循环(迭代)返回一个元素,直到遍历完所有的元素(迭代结束)。

  • 常见可迭代对象:list列表对象,str字符串对象, range对象。

1
2
3
4
5
6
7
my_list = ['dog', 'cat', 'pig']
for i in my_list: # for-in循环
print(i)

# dog
# cat
# pig

任务:如何判断某个对象为可迭代对象?

知识点:

  • 通过isinstance(a, Iterable)方式来判断变量a是否为可迭代对象。
  • 需要从collections模块中导入Iterable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from collections import Iterable

obj = 'hello'
print(type(obj), isinstance(obj, Iterable))
# <class 'str'> True

obj = [1,2,3]
print(type(obj), isinstance(obj, Iterable))
# <class 'list'> True

obj = range(10)
print(type(obj), isinstance(obj, Iterable))
# <class 'range'> True

obj = 123
print(type(obj), isinstance(obj, Iterable))
# <class 'int'> False

两种获取元素索引的方式

知识点:

  • for-in循环体中,并不能直接获得列表元素所对应的索引
  • 只能遍历获取元素,但并不知元素在列表中的位置。

为此,下面给出了两种类似C++的for循环方式来同时获得元素索引

任务:如何获得for循环元素索引?

方法一:设置循环的临时变量i为下标索引。

1
2
3
4
5
my_list = ['dog', 'cat', 'pig']

for i in range(len(my_list)):
print(my_list[i], end=' ')
# dog cat pig

程序解析:

  • range(len(my_list)):对于函数的嵌套写法,应该从里函数len()到外函数range()的顺序来解读程序。
  • 这里使用range()函数,根据my_list列表的长度len(my_list)来构造索引序列。
  • 此时的临时变量i为元素索引。因此,在循环体中,通过下标索引方式访问元素my_list[i]

方法二:引入额外变量来跟踪迭代过程。

1
2
3
4
5
6
7
8
i = 0
for item in my_list:
print(i, ': ', item, sep='')
i += 1

# 0: dog
# 1: cat
# 2: pig

程序解析:

  • 在循环中,引入额外的变量i来跟踪当前循环的迭代情况。
  • i即为列表元素的下标索引。

知识点(补充):

  • print()sep参数,为多个字符串输出添加sep所指定的分割符。
1
2
print('hello', ': ', 'hello', sep='~~')
# hello~~: ~~hello

enumerate()函数获取元素索引

任务:使用enumerate()函数获得元素索引

为解决上述需求,python引入了一种更优雅的方案enumerate()函数,能够在迭代列表的同时获取索引

知识点:

  • 语法:enumerate(iterable, start=0),即

    1
    2
    for index, item in enumerate(iterable, start=0):
    indented_statements
  • 描述:内置函数,生成一系列index-item对(元组),其中index是索引,而item为当前元素。

  • 参数:iterable是之前提到的可迭代对象,可以被遍历的对象。

  • 参数:start自定义索引序号的起始值,默认值为0。每次迭代,enumerate()返回的索引值index = 元素item原来的索引 + 起始值start

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
my_list = ['dog', 'cat', 'pig']
print('--默认起始索引序号start--')
for i, item in enumerate(my_list):
print(i, ': ', item, sep='')

print('--起始索引序号start=2--')
for i, item in enumerate(my_list, 2):
#建议使用format格式化字符串
print('{}: {}'.format(i, item))

# --默认起始索引序号start--
# 0: dog
# 1: cat
# 2: pig
# --起始索引序号start=2--
# 2: dog
# 3: cat
# 4: pig

使用.format()格式化打印元素和序号,格式为:两位数序号.+空格+四位数据,右对齐。

1
2
3
4
5
6
7
8
9
10
fib_list = [1, 2, 4, 5, 8, 13, 21, 34, 55, 89, 144]
format_str = '{:>2}. {:>4}'
for i, item in enumerate(fib_list, 1):
print(format_str.format(i, item))

# 1. 1
# 2. 2
# 3. 4
# 4. 5
# ...

习题

第十五题

题目要求:

  • 打印斐波那契数列fib_list = [1、1、2、3、5、8、13、21、34],输出格式:“第i个元素为XXX”。 分别实现:
    • 手工初始化fib_list,使用range()函数打印斐波那契数列;
    • 手工初始化fib_list,使用enumerate()函数打印斐波那契数列;

代码如下:

1
2
3
4
5
6
7
8
fib_list = [1,1,2,3,5,8,3,21,34]
for i in range(len(fib_list)):
print('第', i, '个元素为', fib_list[i])

print('\n')
format_str = '{:>2}{:>1}{:>4}{:>2}'
for i, item in enumerate(fib_list, 1):
print(format_str.format('第', i, '个元素为', item))

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
第 0 个元素为 1
第 1 个元素为 1
第 2 个元素为 2
第 3 个元素为 3
第 4 个元素为 5
第 5 个元素为 8
第 6 个元素为 3
第 7 个元素为 21
第 8 个元素为 34


第1个元素为 1
第2个元素为 1
第3个元素为 2
第4个元素为 3
第5个元素为 5
第6个元素为 8
第7个元素为 3
第8个元素为21
第9个元素为34

第十六题

题目要求:

  • 斐波那契数列的格式化输出:通过format()格式化字符串输出。模板字符串3个位置索引参数,分别为前个元素、当前元素、当前元素与前一个元素的差;宽度分别设置为3、5、5字宽;由于第1个元素的前一个元素不存在,可以使用if判断只打印索引值大于1的元素输出。

代码如下:

1
2
3
4
5
6
fib_list = [1,1,2,3,5,8,3,21,34]
format_str = '{:>3} {:>5} {:>5}'
for i, item in enumerate(fib_list, 1):
if i==1:
i=i+1
print(format_str.format(fib_list[i-1], item, item-fib_list[i-1]))

运行结果:

1
2
3
4
5
6
7
8
9
 1     1     0
1 1 0
2 2 0
3 3 0
5 5 0
8 8 0
3 3 0
21 21 0
34 34 0

评论