Python 迭代器生成器

  在学习python数据结构的过程中,可迭代对象,迭代器,生成器这些概念参杂在一起,难免让初学者一头雾水,今天就来捋捋这些概览。

可迭代对象(iterable)

  什么是可迭代对象,通俗的讲就是可以直接通过for循环遍历的对象就可称为可迭代对象Iterable,可以使用isinstance()判断一个对象是否是Iterable对象:

>>>from collections import Iterable

>>>isinstance([], Iterable)

True

>>>isinstance({}, Iterable)

True

>>>isinstance('123', Iterable)

True

>>>isinstance(123, Iterable)

False

可迭代对象并不指某种具体的数据类型,list, dict, set, str都是迭代对象,再比如打开状态的files,sockets也是可迭代对象,可迭代对象是指代对象的一种属性,代表该对象是可迭代的。可迭代对象实现了iter方法,该方法返回一个迭代器对象。

迭代器(iterator)

  任何实现了__iter__和__next__方法的对象都是迭代器(python2是实现__iter__和next方法),__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常。可以使用isinstance()判断一个对象是否是Iterator对象:

>>>from collections import Iterator

>>>isinstance([], Iterator)

False

>>>isinstance({}, Iterator)

False

>>>isinstance('123', Iterator)

False

>>>isinstance((x for x in range(10)), Iterator)

True

其中(x for x in range(10))是生成器表达式,它返回的是一个生成器对象,不同于列表生成式[x for x in range(10)]返回一个list对象。生成器对象都是迭代器对象,但list, dict, str虽然是可迭代对象,但不是迭代器对象,可以使用iter()将list, dict, str等可迭代对象变成迭代器对象。

>>>isinstance(iter([]), Iterator)

True

>>>isinstance(iter('123'), Iterator)

True

python的迭代器对象表示一个数据流,可以将这个数据流看作一个有序序列,但我们并不知道序列的长度,只能不断通过调用next()函数实现按需计算下一个数据,因此迭代器的计算是惰性的,只有在需要返回下一个数据时它才计算,迭代器的这种特性可以大大减少内存的开销,迭代器对象甚至可以表示一个无限大的数据流,而让list, dict或者str存储一个无限大的数据流是不可能的。

下面我们通过迭代器来实现斐波那契数列:

  Fib既是一个可迭代对象(因为它实现了__iter__方法),又是一个迭代器(因为实现了__next__方法)。实例变量a和b用于维护迭代器内部的状态。每次调用next()方法的时候做两件事:为下一次调用next()方法修改状态,为当前这次调用生成返回结果。

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

生成器(generator)

  生成器是一种特殊的迭代器,不过这种迭代器更加优雅。它不需要再像上面的类一样写__iter__()和__next__()方法了,只需要一个yiled关键字。

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

fib函数中的yield关键字,将该函数变成了一个生成器,当执行f=fib(10)返回的是一个生成器对象,此时函数中的代码并不会执行,只有显示或隐示地调用next的时候才会真正执行里面的代码,在每次调用next()方法时,遇到yield语句返回值并中断,再次执行时从上次返回的yield语句处继续执行。

生成器是python非常强大的特性,相比其他容器对象它更加节省内存,同时使用更少的代码,使你的代码更加的优雅,凡是以下结构都可以通过生成器重构:

总结

可迭代对象实现了iter方法,该方法返回一个迭代器对象。

迭代器持有一个内部状态的字段,用于记录下次迭代返回值,它实现了__next__和__iter__方法,迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果。

生成器是一种特殊的迭代器,它的返回值不是通过return而是用yield。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181104G1HFPK00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券