一起看看Python中的迭代器&生成器
目录:
- 每篇前言:
- 1.迭代器(iterator)
-
- (1)列表推导式:能够简洁的构造一个新列表
- (2)升级篇 输出1-9之间的偶数 :
- (2)又升一级 如何打印出多个值呢?
- 集合推导式&字典推导式也就呼之欲出了:
- 小拓展:
- 知识点补给站:
- 小拓展:
- 2.生成器(generator)
- (1)元组推导式
- (2)yield
- 迭代器生成器总结:
每篇前言:
🏆🏆作者介绍:【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者
- 🔥🔥本文已收录于Python全栈系列专栏:《Python全栈基础教程》
- 🔥🔥热门专栏推荐:《Django框架从入门到实战》、《爬虫从入门到精通系列教程》、《爬虫高级》、《前端系列教程》、《tornado一条龙+一个完整版项目》。
- 📝📝本专栏面向广大程序猿,为的是大家都做到Python从入门到精通,同时穿插有很多很多习题,巩固学习。
- 🎉🎉订阅专栏后可私聊进一千多人Python全栈交流群(手把手教学,问题解答); 进群可领取Python全栈教程视频 + 多得数不过来的计算机书籍:基础、Web、爬虫、数据分析、可视化、机器学习、深度学习、人工智能、算法、面试题等。
- 🚀🚀加入我一起学习进步,一个人可以走的很快,一群人才能走的更远!
可能很多看了我之前文章的小伙伴会说,我在前面的文章中不是都已经讲的很细了吗?为啥又出一篇文章来讲!
俗话说得好,重要的事情说三遍,而我想说的是,重要的Python知识点要多讲!
同时,本文又来了个新的很重要的知识点——生成器!
1.迭代器(iterator)
迭代是Python最强大的功能之一,是访问集合元素的一种方式。
迭代器是可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问结束为止,迭代器只能往前不会后退。
迭代是一个怎样的过程 ?
- 就是一个依次从数据结构中拿出东西的过程~
(1)列表推导式:能够简洁的构造一个新列表
一般情况下这样构造一个新列表:
# -*- coding: utf-8 -*-"""__author__ = 孤寒者"""li = []for i in range(1,10): li.append(i)print(li) # 输出为:[1, 2, 3, 4, 5, 6, 7, 8, 9]
列表推导式:
li1 = [i for i in range(1,10)]print(li1)# 输出为:[1, 2, 3, 4, 5, 6, 7, 8, 9]
(2)升级篇 输出1-9之间的偶数 :
(当然也可以使用range(1,10,2)
li3 = [i for i in range(1,10) if i % 2 !=0]print(li3)# 输出为:[1, 3, 5, 7, 9]
(2)又升一级 如何打印出多个值呢?
# -*- coding: utf-8 -*-"""__author__ = 孤寒者"""li4 = [(i,j) for i in range(1,5) for j in range(1,5)]print(li4)# 输出为: [(1, 1), (1, 2), (1, 3), (1, 4), # (2, 1), (2, 2), (2, 3), (2, 4), # (3, 1), (3, 2), (3, 3), (3, 4), # (4, 1), (4, 2), (4, 3), (4, 4)]
集合推导式&字典推导式也就呼之欲出了:
集合推导式:
li5 = {i for i in range(1,10)}print(li5)# 输出为:{1, 2, 3, 4, 5, 6, 7, 8, 9}
字典推导式:
li6 = {i:j for i in range(1,10) for j in range(1,10)}print(li6)# 输出为:{1: 9, 2: 9, 3: 9, 4: 9, 5: 9, 6: 9, 7: 9, 8: 9, 9: 9}
小拓展:
li7 = {i:j for i,j in enumerate(['吴某','张某'])}print(li7)# 输出为:{0: '吴某', 1: '张某'}
注意:是没有元组推导式的!!!
知识点补给站:
- 迭代:
for 迭代变量 in 可迭代对象
每一次循环都会自动让“迭代变量”指向“下一个元素”。 - 可迭代对象指:
可迭代对象(实现了__iter__这个方法的都是):序列类型和散列类型。 - 迭代器指:
迭代器(实现了__iter__和__next__方法的就是,迭代器是一个对象) 只能前进不能后退。 - 从可迭代对象生成一个迭代器:
迭代器 = iter(可迭代对象)
下个值 = next(迭代器)
来个例子:
列表是一个可迭代对象,dir查看列表方法的时候里面有__iter__方法,
但列表不是一个迭代器,如何把列表转换为一个迭代器:
li = [1,2,3,4]it = iter(li)
获取迭代器的值?
for i in it: print(i)#这样会取到所有的值
既然是迭代器了,就通过next方法去获取迭代器的值。这样做一次只取一个值,可以省内存空间。
next两种使用方式:
print(it.__next__()) # 输出为:1print(next(it)) # 输出为:2
小拓展:
- for循环实现原理。
# -*- coding: utf-8 -*-"""__author__ = 孤寒者"""li = [1,2,3,4]it = iter(li)try: while True: print(next(it))except Exception as e: print(e)
输出为:
1234
2.生成器(generator)
问题一: 我们如何自己实现一个可迭代对象 ?
在自定义的类中,要实现
__iter__
魔术方法
该魔术方法,必须要返回一个 迭代器
(也需要自己实现)
问题二: 是否有更加优雅的方式 ?
生成器!
- 生成器:返回迭代器的函数。
(1)元组推导式
# -*- coding: utf-8 -*-"""__author__ = 孤寒者"""tu = (i for i in range(1,10))print(type(tu))# 输出为: 意思是这是个生成器print(dir(tu)) # 可知tu里面有方法__iter__和__next__,所以这是个迭代器print(tu.__next__()) # 既然是一个迭代器,就可以使用next方法取值
(2)yield
- 凡是有yield的函数都是生成器!
返回这个对象
yield 一个对象->暂停这个函数
等待下次next重新激活
来个例子:
# -*- coding: utf-8 -*-"""__author__ = 孤寒者"""def fun():# 定义生成器,由next函数触发执行 print('好好学习') yield 1 #返回一个1 并暂停函数 print('天天向上') yield 2 #返回一个2 并暂停函数 print('再来一次') #没有代码了,引发StopIteration异常a = fun()aa = next(a)# 输出为: 好好学习print(aa)# 输出为: 1bb = next(a)# 输出为: 天天向上print(bb)# 输出为: 2# cc = next(a)# 输出为: 再来一次 并抛出StopIteration异常(大家可以自行run一下看看哦~)#如果print(type(fun())),会输出,可见这个函数已经是一个生成器了。
再来个例子看看:
# -*- coding: utf-8 -*-"""__author__ = 孤寒者"""def fun(ele, n): count = 0 while True: if count < n: count += 1 yield ele else: breaka = fun('wumou', 5)for i in a: print(i)
迭代器生成器总结:
生成器 与 迭代器 的区别:
- 生成器,是Python提供的一种非常简便的语法能让我们来自己写出迭代器。
注意——> 生成器,是一种特殊的迭代器。 - 生成器指的是一个函数,返回的结果是一个迭代器。
而迭代器是一个对象。