python容器和迭代器_Python 生成器 迭代器 容器之间的关系

本文详细介绍了Python中的数据结构容器(如list、set、dict等)与可迭代对象、迭代器、生成器的关系。容器是组织元素的数据结构,可迭代对象允许通过for循环遍历,而迭代器是按需生成元素的对象。生成器是一种特殊的迭代器,使用yield关键字,可以在运行时生成值,减少了内存占用。文章还讨论了文件读取时如何利用生成器避免大量内存消耗,并给出了读取文件和查找最长行长度的示例。
摘要由CSDN通过智能技术生成

一、关系图

Python的数据结构容器(container)、可迭代对象(iterable)、迭代器(iterator)、生成器 (generator)、列表/集合/字典推导式(list,set,dict comprehension)之间的关系图

二、容器

容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用 in , not in 关键字判断元素是否包含在容器中。通常这类数据结构把所有的元素存储在内存中。Python的常见的容器对象有:list、set、dict、tuple、str

尽管绝大多数容器都提供了某种方式来获取其中的每一个元素,但这并不是容器本身提供的能力,而是 可迭代对象 赋予了容器这种能力,当然并不是所有的容器都是可迭代的。

三、可迭代对象(iterable)

如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。

刚才说过,很多容器都是可迭代对象,此外还有更多的对象同样也是可迭代对象,比如处于打开状态的files,sockets等等。但凡是可以通过iter()方法返回一 个迭代器 的对象都可称之为可迭代对象。

四、迭代器(iterator)

那么什么迭代器呢?它是一个带状态的对象,他能在你调用 next() 方法的时候返回容器中的下一个值,任何实现了 __next__() 方法的对象都是迭代器,至于它是如何实现的这并不重要。

迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。

五 for i in (iterable)的内部实现

在大多数情况下,我们不会一次次调用next方法去取值,而是通过 for i in (iterable)。

in后面的对象如果是一个迭代器,内部因为有iter方法才可以进行操作,所以,迭代器协议里面有iter和next两个方法,否则for语句无法应用。

六、生成器(generator)

生成器算得上是Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅,它只需要一个 yiled 关键字。

用生成器来实现斐波那契数列的例子是:

#0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

deffab(max_num):

n, a, b= 0, 0, 1

while n

a, b= b, a +b

n= n + 1

for i in fab(5):print(i)

yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,如:fab(5) 。在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b 时,fab 函数就返回一个迭代值, 下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。需要明确的就是生成器也是iterator迭代器,因为它遵循了迭代器协议。

另一种获取生成器的方式:

gen = (x*2 for x in range(10))print(type(gen))########

七、文件读取之生成器

如果直接对文件对象调用 read()或者readlines() 方法,会将整个文件读取到内存中,如果文件非常大,比如上百GB,会导致不可预测的内存占用。好的方法是利用固定长度的缓冲区来不断读取文件内容。通过 yield,我们不再需要编写读文件的迭代类,就可以轻松实现文件读取。

defread_file(fpath):

block_size= 1024with open(fpath,'rb') as f:whileTrue:

block=f.read(block_size)ifblock:yieldblockelse:return

逐行读取:for 循环中的文件句柄 f 就是一个可迭代对象,逐行将内容读取到内存中,内存中永远只保存一行的内容

with open("/hello/abc.txt", "r", encoding="utf-8") as f:for line inf:print(line, end="")

实例:读取文件,找出文件中最长的行的长度:

max(len(x.strip()) for x in open('/hello/abc','r'))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值