Python基础知识7:生成器和迭代器、递归

1、迭代器:

    任何可以用 for in 来迭代读取的都是迭代容器,例如lists、tuples、sets、files、dict、str、生成器等。这些容器中的元素可以逐个地迭代获取。

以下为一个简单的迭代器:

list=[1,2,3,4,5]
for i in list:
print(i)

执行结果:


2、生成器

生成器与普通函数的区别

   生成器是由函数创造的,类似于装饰器,都是在函数上面加上一个东西;而其关键词就是yield,当python看到函数中有yield时,就会将一个普通函数变成一个 generator生成器函数。

生成器(generator)概念:

    生成器不会把结果保存在一个系列中,而是保存生成器的状态,在每次进行迭代时返回一个值,直到遇到StopIteration异常结束。

yield 语句的功能:

    保存上次执行的位置,下次执行时,直接从这个位置开始,而不是一次生成全部的循环。一个函数或者子程序都只能 return 一次,但是一个生成器能暂停执行并返回一个中间的结果


案例1:正常的普通函数执行

def func():#创建普通函数
   
print("start")
return 123
func() #执行函数,打印出来start

执行结果:

案例2:正常的普通函数执行,并调用返回值

def func():#创建普通函数
 
print("start")
return 123
ret=func() #执行函数,打印start
print(ret)#将函数值打印出来,打印函数返回值123

执行结果为:

案例3:增加yield,变成生成器。第一次执行yield后会挂起函数。

因此当调用下面的函数时执行结果为空

def func():#创建普通函数
   print("start")
yield 1#第一次执行yield后,会挂起函数
   yield 2
   yield 3
   return 123
func() #执行函数

目前执行结果为空。

可以打印下函数的返回值看下,是一个生成器

def func():#创建普通函数
   print("start")
yield 1#第一次执行yield后,会挂起函数
   yield 2
   yield 3
   return 123
ret=func() #执行函数
print (ret)

执行结果如下,为生成器:

案例4:当执行循环时,才会进函数取值。

当有循环执行时,会在上次的结果的基础上依次往下执行;

def func():#创建普通函数
   print("start")
yield 1#取第一次循环,并且挂起,把值赋给i
   yield 2
   yield 4
   return 123
ret=func() #执行函数
for i in ret:
print('i',i)

执行结果:

案例5:调用生成器:可以用next控制,每次执行到yield挂起,只取yield之前的内容

    生成器函数在每次暂停执行时,函数体内的所有变量都将被封存(freeze)在生成器中,并将在恢复执行时还原,并且类似于闭包,即使是同一个生成器函数返回的生成器,封存的变量也是互相独立的。      

def func():#创建普通函数
  print("start")
yield 1
  print("a")
yield 2
  print("b")
yield 4
  print("c")
return 123
ret=func() #执行函数
r1=ret.__next__()#进入函数找,执行到第一个yield,挂起,仅获取之前的数据
print(r1)

执行结果:

设置了三个yield,可以调用4次。每个yield执行后挂起,只返回yield之前的内容。

在一个生成器中,如果没有return,则默认执行到函数完毕时返回StopIteration。

如果遇到return,如果在执行过程中 return,则直接抛出 StopIteration 终止迭代。

def func():#创建普通函数
  print("start")
yield 1#增加yield
  print("a")
yield 2
  print("b")
yield 3
  print("c")
return 123
ret=func() #执行函数
r1=ret.__next__()#进入函数找,执行到第一个yield,挂起,仅获取之前的数据
print(r1)
r2=ret.__next__()#接着上次执行的位置,执行到第二个yield,挂起
print(r2)
r3=ret.__next__()#接着上次执行的位置,执行到第三个yield,挂起
print(r3)
r4=ret.__next__()#进入上次执行的位置,执行print("c")
print(r4)

执行结果:

如果第五次就会出错。

def func():#创建普通函数
  print("start")
yield 1#增加yield
  print("a")
yield 2
  print("b")
yield 3
  print("c")
return 123
ret=func() #执行函数
r1=ret.__next__()#进入函数找,执行到第一个yield,挂起,仅获取之前的数据
print(r1)
r2=ret.__next__()#接着上次执行的位置,执行到第二个yield,挂起
print(r2)
r3=ret.__next__()#接着上次执行的位置,执行到第三个yield,挂起
print(r3)
r4=ret.__next__()#进入上次执行的位置,执行print("c")
print(r4)
r5=ret.__next__()#因为已经无yiled,则报错
print(r5)

执行结果:

案例6:生成器需要用迭代器来取数。如下为先使用next取数案例。

每次都从上次挂起的地方继续执行,一直到下一次的yield。

def myrange(arg):
start=0
   while True:
yield start
start+=1
ret=myrange(10)
r1=ret.__next__()#进入函数找到yield,执行完挂起
print(r1)
r2=ret.__next__()#上次挂起的地方,继续执行,直到下一个yield后再挂起
print(r2)

执行结果:

案例7:增加控制条件

def myrange(arg):
start=0
   
while True:
if start>arg:
return
       yield
start
start+=1
ret=myrange(3)
r1=ret.__next__()#进入函数找到yield,执行完挂起,把start赋值给r1
print(r1)
r2=ret.__next__()#上次挂起的地方,继续执行,直到下一个yield后再挂起
print(r2)
r3=ret.__next__()#执行第三次循环
print(r3)
r4=ret.__next__()#执行第四次循环
print(r4)

执行结果:

案例8:使用迭代器来代替next取数

def myrange(arg):
start=0
   
while True:
if start>arg:
return
       yield
start
start+=1
ret=myrange(3)
for item in ret:
print(item)

执行结果:

案例9:迭代器取每个元素

#生成器应用案例:
def flatten(nested):
try:
if isinstance(nested, str):# 如果是字符串,转移到TypeError。
           raise TypeError #引发异常
       for sublist in nested:
for element in flatten(sublist):#把sublist传递给nested,先执行完flatten
               print('got:', element)
except TypeError:#每次执行flatten时都会执行此函数
       yield nested

L = ['aaadf', [1, 2, 3], 20, 40, [55, [66, [88, [99]], 'ddf'], 7]]
for i in flatten(L):
print(i)

执行结果:

3、递归函数

案例10:递归案例,return的值会依次传递

def d():
return '123'
def c():
r=d()
return  r
def b():
r=c()
return r
def a():
r=b()
print(r)
a()

执行结果为123


案例11:递归实现阶乘:实现1*2*3*.....7

def fun(num):
if num==1:
return 1
   
return num*fun(num-1)
x=fun(7)
print(x)

执行结果:5040


参考网页:

http://python.jobbole.com/87805/


案例链接:https://pan.baidu.com/s/1eSAjasM 密码:vblf

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值