我是靠谱客的博主 顺心柜子,最近开发中收集的这篇文章主要介绍python3迭代器是什么_Python3中的迭代器、生成器和,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、迭代器(iterator)

在Python中,for循环可以用于Python中的任何类型,包括列表、元组,字符串等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器 迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发StopIteration。任何这类的对象在Python中都可以用for循环或其他遍历工具迭代,迭代工具内部会在每次迭代时调用next方法,并且捕捉StopIteration异常来确定何时离开。

使用迭代器一个显而易见的好处就是:每次只从对象中读取一条数据,不会造成内存的过大开销。

比如要逐行读取一个文件的内容,利用readlines()方法,我们可以这么写:

for line in open("test.txt").readlines():

print line

这样虽然可以工作,但不是最好的方法。因为他实际上是把文件一次加载到内存中,然后逐行打印。当文件很大时,这个方法的内存开销就很大了。

利用file的迭代器,我们可以这样写:

for line in open("test.txt"):   #use file iterators

print line

这是最简单也是运行速度最快的写法,他并没显式的读取文件,而是利用迭代器每次读取下一行。

迭代器协议

迭代器协议指的是容器类需要包含一个特殊方法 如果一个容器类提供了__iter__()方法,并且该方法能返回一个能够逐个访问容器内所有元素的迭代器,则我们说该容器类实现了迭代器协议。 python中的迭代器协议和for循环是紧密相连的

for x in something:

print(x)

Python 处理 for 循环时,首先会调用内建函数 iter(something),它实际上会调用 something.iter(),返回 something 对应的迭代器。而后,for 循环会调用内建函数 next(),作用在迭代器上,获取迭代器的下一个元素,并赋值给 x。此后,Python 才开始执行循环体

二、生成器(constructor)

生成器函数在Python中与迭代器协议的概念联系在一起。简而言之,包含yield语句的函数会被特地编译成生成器。当函数被调用时,他们返回一个生成器对象,这个对象支持迭代器接口。函数也许会有个return语句,但它的作用是用来yield产生值的。

不像一般的函数会生成值后退出,生成器函数在生成值后会自动挂起并暂停他们的执行和状态,他的本地变量将保存状态信息,这些信息在函数恢复时将再度有效

def g(n):

for i in range(n):

yield i **2

for i in g(5):

print (i)

要了解他的运行原理,我们来用next方法看看:

t = g(5)

t.__next__()

0

t.__next__()

1

t.__next__()

4

t.__next__()

9

t.__next__()

16

t.__next__()

Traceback (most recent call last):

File “”, line 1, in StopIteration

在运行完5次next之后,生成器抛出了一个StopIteration异常,迭代终止。

三、yield表达式 如果一个函数包含了yield表达式,那么这个函数就是一个生成器函数 实际上,yield表达式,只能判断函数是不是生成器函数 与普通函数不同,生成器函数被调用后,其函数体内的代码并不会立即执行,而是返回一个生成器(generator-iterator)。当返回的生成器调用成员方法时,相应的生成器函数中的代码才会执行。

def square():

for i in range(10):

yield i

square_gen=square()

for x in square_gen:

print(x)

前面说到,for 循环会调用 iter() 函数,获取一个生成器;而后调用 next() 函数,将生成器中的下一个值赋值给 x;再执行循环体。因此,上述 for 循环基本等价于:

geniter=square_gen.__iter__

while True:

x=geniter.__next__()

print(x)  #1

geniter.send(3)  #4

geniter.send(10)  #14

注意到,square 是一个生成器函数;作为它的返回值,square_gen 已经是一个迭代器;迭代器的 iter() 返回它自己。因此 geniter 对应的生成器函数,即是 square。

每次执行到 x = geniter.__ next __() 时,square 函数会从上一次暂停的位置开始,一直执行到下一个 yield 表达式,将 yield 关键字后的表达式列表返回给调用者,并再次暂停。注意,每次从暂停恢复时,生成器函数的内部变量、指令指针、内部求值栈等内容和暂停时完全一致。 生成器的方法 生成器有一些方法。调用这些方法可以控制对应的生成器函数;不过,若是生成器函数已在执行过程中,调用这些方法则会抛出 ValueError 异常。

generator.next():从上一次在 yield 表达式暂停的状态恢复,继续执行到下一次遇见 yield 表达式。当该方法被调用时,当前 yield 表达式的值为 None,下一个 yield 表达式中的表达式列表会被返回给该方法的调用者。若没有遇到 yield 表达式,生成器函数就已经退出,那么该方法会抛出 StopIterator 异常。 generator.send(value):和 generator.next() 类似,差别仅在与它会将当前 yield 表达式的值设置为 value。 generator.throw(type[, value[, traceback]]):向生成器函数抛出一个类型为 type 值为 value 调用栈为 traceback 的异常,而后让生成器函数继续执行到下一个 yield 表达式。其余行为与 generator.next() 类似。 generator.close():告诉生成器函数,当前生成器作废不再使用。 举例和说明 如果你看不懂生成器函数 如果你还是不太能理解生成器函数,那么大致上你可以这样去理解。

在函数开始处,加入 result = list(); 将每个 yield 表达式 yield expr 替换为 result.append(expr); 在函数末尾处,加入 return result。

使用 send() 方法与生成器函数通信:

def func():

x = 1

while True:

y = (yield x)

x += y

geniter = func()

geniter.__next__()  #1

geniter.send(3)  #4

geniter.send(12)  #16

此处,生成器函数 func 用 yield 表达式,将处理好的 x 发送给生成器的调用者;与此同时,生成器的调用者通过 send 函数,将外部信息作为生成器函数内部的 yield 表达式的值,保存在 y 当中,并参与后续的处理。

这一特性是使用 yield 在 Python 中使用协程的基础

最后

以上就是顺心柜子为你收集整理的python3迭代器是什么_Python3中的迭代器、生成器和的全部内容,希望文章能够帮你解决python3迭代器是什么_Python3中的迭代器、生成器和所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(70)

评论列表共有 0 条评论

立即
投稿
返回
顶部