Python要想学得好【可迭代对象/迭代器/生成器】少不了!

本文详细解释了Python中的可迭代对象、迭代器和生成器的概念,包括它们的定义、特点、使用场景和创建方法,强调了它们在数据处理中的重要性。同时,文中还通过实例对比了它们的区别,并提供了学习资源链接。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Python数据结构方面光知道字符串、列表、字典这些是还不够的,可迭代对象、迭代器、生成器等这部分也需要弄明白。

虽然是有点难懂,但一步一步来嘛,多点耐心。

首先看一下可迭代对象/迭代器/生成器它们之间的从属关系图:

看不明白没关系,后面会跟大家逐一讲解;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可迭代对象

简单来说就是这个对象是可以迭代的,可以利用 for 来循环的对象都是可迭代对象。

常见的可迭代对象

集合数据类型,如list、tuple、dict、set、str等;

生成器(generator),包括生成器和带yield的生成器函数(generator function)

判断可迭代对象

如何判断一个对象是可迭代对象呢?

可以通过collections模块的Iterable类型判断,具体方法:

from collections import Iterable #导入Iterable 模块;``isinstance(变量, Iterable) #判断一个变量是否为可迭代对象返回True表明是可迭代对象;

特 点

Iterable定义了可返回迭代器的__iter__()方法

__iter__方法的作用是让对象可以用for … in循环遍历,getitem( )方法是让对象可以通过“实例名[index]”的方式访问实例中的元素。

__iter__()方法:

可迭代对象通过__iter__方法通过给我们一个迭代器。

当用户在迭代一个可迭代对象时,实际上就是先获取该对象提供的迭代器,然后通过这个迭代器来一次获取对象中的每一个数据。

具备__iter__方法的对象,就是一个可迭代对象。

>>> from collections import Iterable``   ``>>> class MyList(object):``...     def add(self, item):``...         self.container = []``...     def add(self, item):``...         self.container.append(item)``...     def __iter__(self):``...         """返回一个迭代器"""``...         # 暂时忽略如何构造一个迭代器对象``...         pass``...``>>> mylist = MyList()``>>> isinstance(mylist, Iterable) # mylist对象是一个可迭代对象``True

iter()与next()

对于可迭代对象,可以使用iter()函数得到这些可迭代对象的迭代器,然后对迭代器使用next()函数来获取下一条数据。

(iter()函数调用了可迭代对象的__iter__方法)

>>> list1 = [1, 2, 3]``>>> list1_iter = iter(list1)``>>> next(list1_iter)``1``>>> next(list1_iter)``2``>>> next(list1_iter)``3``>>> next(list1_iter)``Traceback (most recent call last):`  `File "<stdin>", line 1, in <module>``StopIteration

在使用next()迭代完最后一个元素后,再次调用next就会抛出StopIteration异常,以此来告诉我们所有元素均迭代完成。

在用for…in…迭代对象时,如果对象没有实现 __iter__ __next__ 迭代器协议,Python的解释器就会去寻找__getitem__ 来迭代对象。

如果连__getitem__ 都没有定义,这解释器就会报对象不是迭代器的错误:

TypeError: 'Animal' object is not iterable

而实现这个方法后,就可以正常迭代对象了。

class Animal:`    `def __init__(self, animal_list):`        `self.animals_name = animal_list``   `    `def __getitem__(self, index):`        `return self.animals_name[index]``   ``animals = Animal(["dog","cat","fish"])``for animal in animals:`    `print(animal)
dog``cat``fish

需要注意的一点:一个可迭代对象是不能独立的进行迭代的。

Python中,迭代是通过for … in来完成的,凡是可迭代对象都可以直接用for… in…循环访问,这个语句其实做了两件事:

第一件事是调用__iter__()获得一个可迭代器,第二件事是循环调用__next__()。

讲到了可迭代对象,就来讲讲迭代器。

这两个概念常常容易混淆,可能这些概念听起来比较枯燥,但也没得办法,有些抽象的东西就是得强迫自己去试着接受和理解,

迭代器

简单来说只要是实现了__iter__()和__next__的对象,就是迭代器,迭代器就是一个可迭代对象。

总之,迭代器是有__iter__()生成,可以通过__next__进行调用。

迭代器最核心的功能就是可通过__next__方法的调用来返回下一个值,若该元素没有了,就抛出StopIteration异常。

调用next()方法

迭代器每次调用next()方法的时候做两件事:

  • 为下一次调用next()方法修改状态

  • 生成当前调用的返回结果

需要注意的是迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果(不同于容器)。

讲到容器,这里补充一点,容器实际上是不存在的,它并不是一种数据类型。

说白了,它的作用就像它的名字一样:用来存放东西(数据)。常见的容器类型有列表(list)、元组(tuple)、字符串(str)、字典(dict)以及集合(set )。

使用场景

  • for 循环

  • 扩展集合类型

  • 列表推导、字典推导、集合推导

  • 元组拆包

  • 调用函数,使用*拆包实参等

特 点

可迭代:迭代器内部实现了__ iter __ 方法,所以它可迭代。

易损耗:迭代器经过一次逐次取值的循环后便耗尽了,若想再次迭代须重建迭代器。

模式:按需要一次获取一个数据。

举例:下面的a就是一个迭代器,和可迭代对象title不同,a可以通过next(a)来逐个获取其中的每个元素。

title = ['Python','Java','C++'] # 列表是一个可迭代对象``isinstance(title,Iterable)      # True``a = iter(title) # 由可迭代对象的iter方法返回一个迭代器``>>> next(a)``Python``>>> next(a)``Java``>>> next(a)``C++` `>>> next(a)  # 抛出StopIteration异常

如果使用next(title)则会报TypeError错,显示列表对象不是一个迭代器。

>>> next(title)`  `TypeError: 'list' object is not an iterator

总之如果一个对象拥有__ next __ ()方法,该对象是迭代器。

可迭代对象和迭代器小结:

A、迭代器一定拥有 __ iter __ 方法、__ next __ 方法,而可迭代对象一定拥有 __ iter __ 方法,但不能实现 __ next __ 方法,也是迭代器一定是可迭代对象,但可迭代对象不一定是迭代器。

B、容器类型(list tuple dict str set )是可迭代对象但不是迭代器。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

生成器

生成器是真实存在于Python中的对象,与容器这种概念词是不同的,它是可以直接通过next()进行调用的。

概念介绍

  • 生成器函数:拥有yield关键字的Python函数。

  • 生成器表达式:制造生成器的工厂,支持惰性产值。

  • 生成器工厂函数:返回生成器的函数,定义体中可以没有yield关键字。

生成器也是函数,函数中只要有yield关键字,那么它就是生成器函数,返回值为生成器。

生成器存在 __ inter __ 、 __ next __ 两种方法(不需要手动实现两种方法),因此它是一个迭代器。

创建方法

  • 第一种创建方法跟列表推导式是差不多的,就是 [] 换成了();

  • 第二种创建方法:使用yield;

为什么使用生成器?

为什么列表代替不了生成器?因为列表容量肯定有限的,如创建一个包含666万个元素列表,不仅占用很大的存储空间,若我们仅仅需要访问前面几个元素,那后面绝大数元素占用空间都白浪费。

在Python中这种一边循环一边计算的机制,称为生成器(Generator),生成器一次只能产生一个值,这样消耗的内存数量将大大减少。

生成器函数

只要Python函数的定义体中有yield关键字,该函数就是生成器函数,调用生成器函数时,会返回一个生成器对象。

简单来理解:生成器函数是生成器工厂,普通函数与生成器函数区别在于定义体中yield关键字。

生成器可以通过for循环迭代,这一点和迭代器中的next()函数功能相同,如下我们使用一个有限序列作为例子,如果是无限序列,则会无休止的循环下去。

def d():`    `yield 1`    `yield 2`    `yield 3`    `yield 4``for i in d():`    `print(i)``type(d()) # generator``isinstance(d(),Iterator) # True``isinstance(d(),Iterable) # True

得到如下结果:(也可以看出生成器即是迭代器,也是可迭代对象)

1``2``3``4``generator

小结:

  • 生成器函数执行时,并不会执行函数体;

  • 当next生成器时,会从当前代码执行到之后的第一个yield,会弹出值并暂停函数;

  • 当再次执行next生成器时,从上次暂停处开始向下执行;

  • 当没有多余yield时,会抛出StopIteration异常,异常的值是函数的返回值;

yield关键字

函数中使用yield关键字,这个函数就变成了生成器函数。

yield只能定义在函数中,当我们调用这个函数时,函数内部代码并不会立即执行,这个函数会返回一个生成器对象,当我们使用for对其进行迭代时,函数内的代码才会被执行。

yield与return区别:

(1)return时,这个函数的局部变量都被销毁,所以的return都是已经得到了结果将其返回。

(2)yield是产生一个可以恢复的生成器函数,恢复了局部变量,生成器只有在调用next()方法时,才运行函数生成一个结果。

(3)yield会记住函数执行的位置,下次再执行的时会从上次的位置继续向下执行;若再函数中使用return,函数就直接退出,无法继续执行。

小结:

  • 具有yield关键字的函数都是生成器;

  • yield可以理解为return,返回的值给调用者,不同return返回后,函数会被释放,而生成器不会。

  • 直接调用next方法或for语句j进行一下次迭代时,生成器会从yield下一句开始执行,遇到下一个yield为止,若没有yield 会抛出StopIteration。

生成器表达式

生成器表达式可理解为列表推导的惰性版本,不会迫切构建列表,而是返回一个生成器,按惰性生成元素。

生成器表达式,将列表推导中的[ ]替换为( ),让代码表的更整洁。

举个例子:

>>> [x*x for x in range(10)] # 列表生成式``[0, 1, 4, 9, 16]``>>> (x*x for x in range(10)) # 生成器表达式``<generator object <genexpr> at 0x401f08>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

总 结

(1)什么是可迭代对象?

可迭代对象要么实现了能返回迭代器的 iter 方法,要么实现了 getitem 方法而且其参数是从零开始的索引。

(2)什么是迭代器?

迭代器是这样的对象:实现了无参数的 next 方法,返回下一个元素,如果没有元素了,那么抛出 StopIteration 异常;并且实现iter 方法,返回迭代器本身。

(3)什么是生成器?

生成器是带有 yield 关键字的函数。调用生成器函数时,会返回一个生成器对象。

(4)什么是生成器表达式?

生成器表达式是创建生成器的简洁句法,这样无需先定义函数再调用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以上就是“Python要想学得好【可迭代对象/迭代器/生成器】少不了!”的全部内容,希望对你有所帮助。

关于Python技术储备

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

在这里插入图片描述

二、Python必备开发工具

img

三、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

img

五、Python练习题

检查学习结果。

img

六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

img

最后祝大家天天进步!!

上面这份完整版的Python全套学习资料已经上传至优快云官方,朋友如果需要可以直接微信扫描下方优快云官方认证二维码免费领取【保证100%免费】。

”的全部内容,希望对你有所帮助。

关于Python技术储备

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

在这里插入图片描述

二、Python必备开发工具

img

三、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

img

五、Python练习题

检查学习结果。

img

六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

img

最后祝大家天天进步!!

上面这份完整版的Python全套学习资料已经上传至优快云官方,朋友如果需要可以直接微信扫描下方优快云官方认证二维码免费领取【保证100%免费】。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值