迭代器和可迭代对象
先说什么是可迭代对象:
简单通俗 可以被for循环迭代的对象就是可迭代对象。
可以使用isinstance()判断一个对象是否是Iterable对象:
>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
迭代器
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
可以使用isinstance()判断一个对象是否是Iterator对象:
>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
可以用iter()函数将可迭代对象转换成迭代器
so:字典、列表、字符串是可迭代对象,而不是迭代器
生成器既是迭代器也是可迭代对象
生成器(generator)概念
网上很多概念 例如:生成器不会把结果保存在一个系列中,而是保存生成器的状态,在每次进行迭代时返回一个值,直到遇到Stoplteration一行结束。
其实说白了 生成器 就是 一个对象,每次迭代的时候把正在被迭代的值返回。而其他值不存在于内存中。
生成器语法
生成器表达式
gen = (x**2 for x in range(10))
这样gen就是一个生成器了,看着和列表推导式是不是看起来很像,只不过把[]换成()
这里不光看起来像,作用也差不多,区别呢:生成器把一个对象放到内存中,而列表是把数据放到内存中。
next(gen)# 0
next(gen)# 1
next(gen)# 4
……
调用的时候可以看出来和列表的区别了吧。生成器只能从第一个开始迭代,不可跳着选,不可指定范围,也不能倒叙输出,只能从头一次迭代。
如果迭代次数过多了,会出现一个异常。
Traceback (most recent call last):
File "D:/Code/de.py", line 32, in <module>
print(next(gen))
StopIteration
或许会发现用到了一个next(gen)方法,等同于gen.next()。第二种方法不推荐使用。
可以被for循环迭代的都是可迭代对像
生成器也是一个可迭代对象
for i in gen:
print(i)
嗯哼?直接可以输出了。next呢? 其实Python的for循环的本质就是通过不断调用next()函数实现的,而且内部做了StopIteration异常处理
生成器函数
当函数中出现yield的时候,这个函数就不是一个普通的函数了,而是一个生成器函数
def gen(max):
k,a,b = 0,0,1
while k < max:
yield b
a, b = b, a+b
k += 1
所有教程常见举例,斐波那契数列。这时gen函数就是一个生成器了
print(gen(10)) #<generator object fbnq at 0x03094420>
for i in gen(10):
print(i)
yield可以简单理解成return。当执行到yield的时候会退出函数 等待下次继续调用。