Python 迭代器和生成器

本文详细介绍了 Python 中的迭代器和生成器概念,包括如何创建和使用迭代器,生成器的基础语法及高级应用,如 send、throw 和 close 方法。此外,还探讨了生成器与协同程序的关系,并通过代码示例展示了这些概念的实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

迭代器 
迭代器只不过是一个实现迭代器协议的容器对象。它基于两个方法: 
  • next 返回容器的写一个项目;
  • __iter__ 返回迭代器本身。


迭代器可以通过使用一个iter内建函数和一个序列来创建,示例如下。 
Python代码  收藏代码
  1. >>> i = iter('abc')  
  2. >>> i.next()  
  3. 'a'  
  4. >>> i.next()  
  5. 'b'  
  6. >>> i.next()  
  7. 'c'  
  8. >>> i.next()  
  9. Traceback (most recent call last):  
  10.   File "<stdin>", line 1in <module>  
  11. StopIteration  

引用
当序列遍历完时,将抛出一个StopIteration异常。这将使迭代器与循环兼容,因为它将捕获这个异常以停止循环。要创建定制的迭代器,可以编写一个具有next方法的类,只要该类能够提供返回迭代器实例的__iter__特殊方法。

Python代码  收藏代码
  1. class MyIterator(object):  
  2.     def __init__(self, step):  
  3.         self.step = step  
  4.   
  5.     def next(self):  
  6.         if self.step == 0:  
  7.             raise StopIteration  
  8.         self.step -= 1  
  9.         return self.step  
  10.   
  11.     def __iter__(self):  
  12.         return self  
  13.   
  14. for el in MyIterator(4):  
  15.     print el  

生成器 
引用
生成器提供了一种出色的方法,使得需要返回一系列元素的函数所需的代码更加简单、高效。基于yield指令,可以暂停一个函数并返回中间结果。该函数将保存执行环境并且可以在必要时恢复。 

Python代码  收藏代码
  1. #!/usr/bin/env python  
  2. #-*-coding:utf-8-*-  
  3.   
  4. def fibonacci():  
  5.     a, b = 01  
  6.     while  True:  
  7.         yield b  
  8.         a, b = b, a + b  
  9.   
  10. fib = fibonacci()  
  11. print [fib.next() for i in range(10)]  
  12. print map(lambda x,f = lambda x,f:f(x-1,f)+f(x-2,f) if x >1 else x:f(x,f),range(10))  


Python引入的与生成器相关的最后一个特性是提供了与next方法调用的代码进行交互的功能。yield将变成一个表达式,而一个值可以通过名为send的新方法来传递,如下所示。 
Python代码  收藏代码
  1. def psychologist():  
  2.     print 'Please tell me your problems'  
  3.     while True:  
  4.         answer = (yield)  
  5.         if answer is not None:  
  6.             if answer.endswith('?'):  
  7.                 print ("Don't ask yourself too much questions")  
  8.             elif 'good' in answer:  
  9.                 print "A that's good, go on"  
  10.             elif 'bad' in answer:  
  11.                 print "Don't be so negative"  
  12.   
  13. free = psychologist()  
  14. free.next()  
  15. free.send('I feel bad')  
  16. free.send("?")  
  17. free.send("ok then i should find what is good for me")  


Output: 
Please tell me your problems 
Don't be so negative 
Don't ask yourself too much questions 
A that's good, go on 

send的工作机制与next一样,但是yield将变成能够返回传入的值。因而,这个函数可以根据客户端代码来改变其行为。同时,还添加了throw和close两个函数,以完成该行为。它们将向生成器抛出一个错误: 
throw 允许客户端代码传入要抛出的任何类型的异常; 
close的工作方式是相同的,但是将会抛出一个特定的异常——GeneratorExit,在这种情况下,生成器函数必须再次抛出GeneratorExit或StopIteration异常。 
Python代码  收藏代码
  1. def my_generator():  
  2.     try:  
  3.         yield 'something'  
  4.     except ValueError:  
  5.         yield 'dealing with the exception'  
  6.     finally:  
  7.         print "ok let's clean"  
  8.   
  9. gen = my_generator()  
  10. print gen.next()  
  11. print gen.throw(ValueError('mean mean mean'))  
  12. gen.close()  
  13. print gen.next()  


finally部分在之前的版本是不允许使用的,它将捕获任何未被捕获的clise和throw调用,是完成清理工作的推荐方式。 
协同程序 

协同程序是可以挂起、回复,并且有多个进入点的函数。它们可以实现协同的多任务和管道机制。例如:每个协同程序将消费或生产的数据,然后暂停,直到其他数据被传递。 
在Python中,协同程序的替代者是线程,它可以实现代码块之前的交互。但是因为它们表现出一种抢先式的风格,所以必须注意资源锁,而协同程序不需要。这样的代码可能变得相当复杂,难以创建和调试。但是生成器几乎就是协同程序,添加send、throw和close其初始的意图就是为该语言提供一种类似协同程序的特性。 

使用multimask模块 
Python代码  收藏代码
  1. #!/usr/bin/env python  
  2. # -*- coding:utf-8 -*-  
  3. import multitask  
  4.   
  5. def coroutine_1():  
  6.     for i in range(3):  
  7.         print 'c1'  
  8.         yield i   
  9.   
  10. def coroutine_2():  
  11.     for i in range(3):  
  12.         print 'c2'  
  13.         yield i  
  14.   
  15. multitask.add(coroutine_1())  
  16. multitask.add(coroutine_2())  
  17. multitask.run()  

在协同程序之间的写作,最经典的例子是接受来自多个客户的查询,并将每个查询委托给对此作出相应的新线程的服务器应用程序。 
Python代码  收藏代码
  1. #!/usr/bin/env python  
  2. # -*- coding:utf-8 -*-  
  3.   
  4. from __future__ import with_statement  
  5. from contextlib import closing  
  6. import socket  
  7. import multitask  
  8.   
  9. def client_handler(sock):  
  10.     while closing(sock):  
  11.         while True:  
  12.             data = (yield multitask.recv(sock, 1024))  
  13.             if not data:  
  14.                 break  
  15.             yield multitask.send(sock, data)  
  16.   
  17. def echo_server(hostname, port):  
  18.     addrinfo = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC,socket.SOCK_STREAM)  
  19.     (family, socktype, proto, cannoname, sockaddr) = addrinfo[0]  
  20.     with closing(socket.socket(family,socktype,proto)) as sock:  
  21.         sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)  
  22.         sock.bind(sockaddr)  
  23.         sock.listen(5)  
  24.         while True:  
  25.             multitask.add(client_handler((yield multitask.accept(sock))[0]))  
  26.   
  27. if __name__ == "__main__":  
  28.     import sys  
  29.     hostname = None  
  30.     port = 1111  
  31.     if len(sys.argv) > 1:  
  32.         hostname = sys.argv[1]  
  33.     if len(sys.argv) > 2:  
  34.         port = int(sys.argv[2])  
  35.     multitask.add(echo_server(hostname,port))  
  36.     try:  
  37.         multitask.run()  
  38.     except KeyboardInterrupt:  
  39.         pass  


生成器表达式 
Python代码  收藏代码
  1. >>> iter = (x**2 for x in range(10if x % 2 == 0)  
  2. >>> for el in iter:  
  3. ... print el  
  4. …   
  5. 0  
  6. 4  
  7. 16  
  8. 36  
  9. 64  

itertools模块 
islice:窗口迭代器 
tee:往返式的迭代器 
groupby:uniq迭代器 
Python代码  收藏代码
  1. #!/usr/bin/env python  
  2. #-*-coding:utf-8-*-  
  3.   
  4. from itertools import group by  
  5. def compress(data):  
  6.     return ((len(list(group)),name) for name,group in groupby(data))  
  7.   
  8. def decompress(data):  
  9.     return (car * size for size, car in data)  
  10.   
  11. print list(compress('get uuuuuuuuuuuuuuuup'))  
  12. compressed = compress('get uuuuuuuuuuuuuuuup')  
  13. print ''.join(decompress(compressed))  
基于Spring Boot搭建的一个多功能在线学习系统的实现细节。系统分为管理员用户两个主要模块。管理员负责视频、文件文章资料的管理以及系统运营维护;用户则可以进行视频播放、资料下载、参学习论坛并享受个性化学习服务。文中重点探讨了文件下载的安全性性能优化(如使用Resource对象避免内存溢出),积分排行榜的高效实现(采用Redis Sorted Set结构),敏感词过滤机制(利用DFA算法构建内存过滤树)以及视频播放的浏览器兼容性解决方案(通过FFmpeg调整MOOV原子位置)。此外,还提到了权限管理方面自定义动态加载器的应用,提高了系统的灵活性易用性。 适合人群:对Spring Boot有一定了解,希望深入理解其实际应用的技术人员,尤其是从事在线教育平台开发的相关从业者。 使用场景及目标:适用于需要快速搭建稳定高效的在线学习平台的企业或团队。目标在于提供一套完整的解决方案,涵盖从资源管理到用户体验优化等多个方面,帮助开发者更好地理解掌握Spring Boot框架的实际运用技巧。 其他说明:文中不仅提供了具体的代码示例技术思路,还分享了许多实践经验教训,对于提高项目质量有着重要的指导意义。同时强调了安全性、性能优化等方面的重要性,确保系统能够应对大规模用户的并发访问需求。
标题基于SpringBoot的学生学习成果管理平台研究AI更换标题第1章引言介绍研究背景、目的、意义以及论文结构。1.1研究背景目的阐述学生学习成果管理的重要性及SpringBoot技术的优势。1.2研究意义分析该平台对学生、教师及教育机构的意义。1.3论文方法结构简要介绍论文的研究方法整体结构。第2章相关理论技术概述SpringBoot框架、学习成果管理理论及相关技术。2.1SpringBoot框架简介介绍SpringBoot的基本概念、特点及应用领域。2.2学习成果管理理论基础阐述学习成果管理的核心理论发展趋势。2.3相关技术分析分析平台开发所涉及的关键技术,如数据库、前端技术等。第3章平台需求分析设计详细分析平台需求,并设计整体架构及功能模块。3.1需求分析从学生、教师、管理员等角度对平台需求进行深入分析。3.2整体架构设计设计平台的整体架构,包括技术架构逻辑架构。3.3功能模块设计具体设计平台的核心功能模块,如成果展示、数据分析等。第4章平台实现测试阐述平台的实现过程,并进行功能测试性能分析。4.1平台实现详细介绍平台的开发环境、关键代码实现及技术难点解决方案。4.2功能测试对平台各项功能进行全面测试,确保功能正确无误。4.3性能分析分析平台的性能指标,如响应时间、并发处理能力等。第5章平台应用效果评估探讨平台在实际教学中的应用,并对其效果进行评估。5.1平台应用案例选取典型应用案例,展示平台在实际教学中的使用情况。5.2效果评估方法介绍平台效果评估的具体方法指标。5.3评估结果分析根据评估数据,对平台的应用效果进行深入分析。第6章结论展望总结论文的主要研究成果,并指出未来研究方向。6.1研究结论概括性地阐述论文的研究结论主要贡献。6.2研究展望针对当前研究的不足之处,提出未来改进扩展的方向。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值