写在前面:
快速学,就看这一套课程就够了,全网播放量超过2000万次。
当然如果大家觉得这套课程有点“旧”,黑马程序员还有最新的Python课程,8天带你学会!
零基础的学习笔记也给大家整理好了,可以参考学习:
- Python从变量到数据类型 / 输出格式大全!代码都可复制
- 基础学习输入 /转换数据类型的函数 / 算数、赋值、复合赋值、比较、逻辑运算符
- 条件语句边学边练,习题均有答案 / while的语法和应用 /while循环嵌套以及练习题
- 字符串 / Python列表的常用操作 / 元祖 / 集合 / 公共操作
- 推导式学习 / 函数 / 函数 / 文件的基本操作汇总(上) / 基本操作汇总(下)
- 面向对象基础篇 / 面向对象之魔法方法 / 面向对象实际案例:烤地瓜和搬家具
- 继承 / 面向对象的三大特征 / 异常学习 / 模块 / 包 / 面向对象版学员管理系统
下面开始正式回答题主问题!
一、迭代
迭代是Python最强大的功能之一,是访问集合元素的一种方式。
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
迭代器有两个基本的方法:iter() 和 next()。
字符串,列表或元组对象都可用于创建迭代器:
>>> list=[1,2,3,4]
>>> it = iter(list) # 创建迭代器对象
>>> print (next(it)) # 输出迭代器的下一个元素
1
>>> print (next(it))
2
>>>
迭代器对象可以使用常规for语句进行遍历:
#!/usr/bin/python3
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
for x in it:
print (x, end=" ")
执行以上程序,输出结果如下:
1 2 3 4
也可以使用 next() 函数:
#!/usr/bin/python3
import sys # 引入 sys 模块
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
while True:
try:
print (next(it))
except StopIteration:
sys.exit()
执行以上程序,输出结果如下:
1
2
3
4
创建一个迭代器
把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。
如果你已经了解的面向对象编程,就知道类都有一个构造函数,Python 的构造函数为 __init__(), 它会在对象初始化的时候执行。
更多内容查阅:Python3 面向对象
__iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。
__next__() 方法(Python 2 里是 next())会返回下一个迭代器对象。
创建一个返回数字的迭代器,初始值为 1,逐步递增 1:
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
执行输出结果为:
1
2
3
4
5
StopIteration
StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。
在 20 次迭代后停止执行:
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 20:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
print(x)
执行输出结果为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
二、while循环嵌套
2.1 应用场景
故事概述:上一篇我们说了女朋友生气了,惩罚我们说3遍“媳妇⼉, 我错了”,这个程序是不是循环即可?但如果⼥朋友说:还要刷今天晚饭的碗,这个程序怎么书写?
while 条件:
print('媳妇⼉, 我错了')
print('刷晚饭的碗')
但如果女朋友还是生气,把这套惩罚要连续3天都执⾏,有如何书写程序?
while 条件:
while 条件:
print('媳妇⼉, 我错了')
print('刷晚饭的碗')
2.2 语法
while 条件1:
条件1成⽴执⾏的代码
......
while 条件2:
条件2成⽴执⾏的代码
......
所谓while循环嵌套,就是一个while里面嵌套了一个while的方法,没个while和之前的基础语法都是相同的。
2.3 快速体验:复现场景
代码:
j = 0
while j < 3:
i = 0
while i < 3:
print('媳妇⼉,我错了')
i += 1
print('刷晚饭的碗')
print('⼀套惩罚结束----------------')
j += 1
执行结果:
理解这个流程:
当内部循环执行完成之后,再执行下一次外部循环的条件判断。
三、while循环嵌套应用
3.1 应用一:打印星号(正方形)
需求:
*****
*****
*****
*****
*****
代码:
分析:一行输出5个星号,重复打印5行。
# 重复打印5⾏星星
j = 0
while j <= 4:
# ⼀⾏星星的打印
i = 0
while i <= 4:
# ⼀⾏内的星星不能换⾏,取消print默认结束符\n
print('*', end='')
i += 1
# 每⾏结束要换⾏,这⾥借助⼀个空的print,利⽤print默认结束符换⾏
print()
j += 1
3.2 应用二:打印星号(三角形)
需求:
*
**
***
****
*****
代码:
分析: ⼀⾏输出星星的个数和⾏号是相等的,每⾏:重复打印⾏号数字个星号,将打印⾏星号的命令重 复执⾏5次实现打印5⾏。
# 重复打印5⾏星星
# j表示⾏号
j = 0
while j <= 4:
# ⼀⾏星星的打印
i = 0
# i表示每⾏⾥⾯星星的个数,这个数字要和⾏号相等所以i要和j联动
while i <= j:
print('*', end='')
i += 1
print()
j += 1
3.3 九九乘法表
执行结果:
代码:
# 重复打印9⾏表达式
j = 1
while j <= 9:
# 打印⼀⾏⾥⾯的表达式 a * b = a*b
i = 1
while i <= j:
print(f'{i}*{j}={j*i}', end='\t')
i += 1
print()
j += 1
四、for循环
4.1 语法
for 临时变量 in 序列:
重复执⾏的代码1
重复执⾏的代码2
......
4.2 快速体验
str1 = 'itheima'
for i in str1:
print(i)
执行结果:
4.3 break
str1 = 'itheima'
for i in str1:
if i == 'e':
print('遇到e不打印')
break
print(i)
执行结果:
4.4 continue
str1 = 'itheima'
for i in str1:
if i == 'e':
print('遇到e不打印')
continue
print(i)
执行结果:
五、else
循环可以和else配合使用,else下⽅缩进的代码指的是当循环正常结束之后要执⾏的代码。
5.1 while...else
需求:⼥朋友⽣⽓了,要惩罚:连续说5遍“媳妇⼉,我错了”,如果道歉正常完毕⼥朋友就原谅我了,这个程序怎么写?
i = 1
while i <= 5:
print('媳妇⼉,我错了')
i += 1
print('媳妇⼉原谅我了...')
思考:这个print是不是没有循环也能执行?
语法:
while 条件:
条件成⽴重复执⾏的代码
else:
循环正常结束之后要执⾏的代码
示例:
i = 1
while i <= 5:
print('媳妇⼉,我错了')
i += 1
else:
print('媳妇原谅我了,真开⼼,哈哈哈哈')
5.2 退出循环的方式
需求:⼥朋友⽣⽓,要求道歉5遍:媳妇⼉,我错了。道歉到第三遍的时候,媳妇埋怨这⼀遍说的不真 诚,是不是就是要退出循环了?这个退出有两种可能性:
- 更生气,不捣蒜原谅也不需要道歉了,这个程序如何书写?
- 只一遍不真诚,可以忍受,继续下一次道歉,这个程序如何书写?
(1)break
i = 1
while i <= 5:
if i == 3:
print('这遍说的不真诚')
break
print('媳妇⼉,我错了')
i += 1
else:
print('媳妇原谅我了,真开⼼,哈哈哈哈')
所谓else指的是循环正常结束之后要执⾏的代码,即如果是break终⽌循环的情况,else下⽅缩进 的代码将不执⾏。
(2)continue
i = 1
while i <= 5:
if i == 3:
print('这遍说的不真诚')
i += 1
continue
print('媳妇⼉,我错了')
i += 1
else:
print('媳妇原谅我了,真开⼼,哈哈哈哈')
因为continue是退出当前⼀次循环,继续下⼀次循环,所以该循环在continue控制下是可以正常 结束的,当循环结束后,则执⾏了else缩进的代码
5.3 for...else
语法:
for 临时变量 in 序列:
重复执⾏的代码
...
else:
循环正常结束之后要执⾏的代码
所谓else指的是循环正常结束之后要执⾏的代码,即如果是break终⽌循环的情况,else下⽅缩进的代码将不执⾏。
示例:
str1 = 'itheima'
for i in str1:
print(i)
else:
print('循环正常结束之后执⾏的代码')
退出循环的方式:
(1)break终⽌循环
str1 = 'itheima'
for i in str1:
if i == 'e':
print('遇到e不打印')
break
print(i)
else:
print('循环正常结束之后执⾏的代码')
执行结果:
没有执⾏else缩进的代码。
(2)continue控制循环
str1 = 'itheima'
for i in str1:
if i == 'e':
print('遇到e不打印')
continue
print(i)
else:
print('循环正常结束之后执⾏的代码')
执行结果:
因为continue是退出当前⼀次循环,继续下⼀次循环,所以该循环在continue控制下是可以正常 结束的,当循环结束后,则执⾏了else缩进的代码。
总结
- 循环的作⽤:控制代码重复执⾏
- while语法
while 条件:
条件成⽴重复执⾏的代码1
条件成⽴重复执⾏的代码2
......
- while循环嵌套语法
while 条件1:
条件1成⽴执⾏的代码
......
while 条件2:
条件2成⽴执⾏的代码
......
- for循环语法
for 临时变量 in 序列:
重复执⾏的代码1
重复执⾏的代码2
......
- break退出整个循环
- continue退出本次循环,继续执⾏下⼀次重复执⾏的代码
- else
while和for都可以配合else使⽤
else下⽅缩进的代码含义:当循环正常结束后执⾏的代码
break终⽌循环不会执⾏else下⽅缩进的代码
continue退出循环的⽅式执⾏else下⽅缩进的代码
六、递归
什么是Python中的递归?
递归是根据自身定义某些内容的过程。
一个物理世界的示例是放置两个彼此面对的平行反射镜。它们之间的任何对象都将递归地反映出来。
Python递归函数
在Python中,我们知道一个函数可以调用其他函数。函数甚至可能会调用自身。这些类型的构造称为递归函数。
以下是查找整数的阶乘的递归函数的示例。
数字的阶乘是从1到该数字的所有整数的乘积。例如,阶乘6(表示为6!)是1 * 2 * 3 * 4 * 5 * 6 = 720。
递归函数示例
示例def calc_factorial(x): """这是一个 求整数阶乘的递归函数""" if x == 1: return 1 else: return (x * calc_factorial(x-1)) num = 4 print("The factorial of", num, "is", calc_factorial(num))
在上面的示例中,它calc_factorial()是一个递归函数,它调用了自己。
当我们用正整数调用此函数时,它将通过减少数量来递归调用自身。
每个函数将数字乘以该数字下面的数字的阶乘,直到它等于1。可以在以下步骤中解释此递归调用。
calc_factorial(4) # 1st call with 4
4 * calc_factorial(3) # 2nd call with 3
4 * 3 * calc_factorial(2) # 3rd call with 2
4 * 3 * 2 * calc_factorial(1) # 4th call with 1
4 * 3 * 2 * 1 # return from 4th call as number=1
4 * 3 * 2 # return from 3rd call
4 * 6 # return from 2nd call
24 # return from 1st call
当数字减少到1时,递归结束。这称为基本条件。
每个递归函数必须具有停止递归的基本条件,否则该函数将无限调用自身。
Python解释器限制了递归的深度,以帮助避免无限递归,从而导致堆栈溢出。
默认情况下,最大递归深度为 1000。如果超出限制,则结果为RecursionError。让我们看一个这样的条件。
示例def recursor(): recursor() recursor()
输出结果
Traceback (most recent call last):
File "<string>", line 3, in <module>
File "<string>", line 2, in a
File "<string>", line 2, in a
File "<string>", line 2, in a
[Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded
递归的优点
- 递归函数使代码看起来干净整洁。
- 使用递归可以将复杂的任务分解为更简单的子问题。
- 与使用嵌套嵌套相比,使用递归更容易生成序列。
递归的缺点
- 有时,递归背后的逻辑很难遵循。
- 递归调用很昂贵(效率低),因为它们占用大量内存和时间。
- 递归函数很难调试。