生成器
1.列表生成式
在讲生成器之前,先说一个和生成器作用很类似的东西,列表生成式,其格式为:
[ X for X in Y]
X为一个元素,Y为一个范围,列表生成式将Y中的元素一个一个的取出来,组成一个列表
使用命令行打开Python3
定义一个列表生成式L,并将其输出
>> L = [ x*2 for x in range(5)]
>> L
Out: [0, 2, 4, 6, 8]
2.生成器简介
在Python中,通过列表生成式,我们可以直接创建⼀个列表,但列表容量是有限的,而且创建⼀个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的列表,从而节省大量的空间
在Python中,这种⼀边循环创建元素⼀边计算的机制,称为生成器:generator
3.使用表达式的方式创建生成器
表达式生成器的格式和列表生成式的格式很相似,不过生成器使用小括号:
( X for X in Y )
生成器每次只生成一个元素,取出其中的元素,可以通过next方法
>> G = ( x*2 for x in range(2))
>> next(G)
Out: 0
>> next(G)
Out: 1
>> next(G)
Out:
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-24-380e167d6934> in <module>()
----> 1 next(G)
StopIteration:
生成器保存的是算法,每次调⽤ next(G) ,就计算出 G 的下⼀个元素的值,直到计算到最后⼀个元素,没有更多的元素时,抛出 StopIteration 的异常
使用next方法取元素太麻烦,也可以使用for循环
>> G = ( x*2 for x in range(2))
>> for x in G:
print(x)
Out: 0
2
>>
4.使用函数方式创建生成器
generator非常强⼤。如果推算的算法比较复杂,用类似列表生成式的 for 循环无法实现的时候,就需要用函数来实现生成器,实现时还必须要到yield关键字
例如斐波那契数列的生成算法,需要使用一个函数来实现
def fib(times):
n = 0
a,b = 0,1
while n<times:
print(b)
a,b = b,a+b
n+=1
return 'done'
fib(5)
上面的函数直接将元素输出了,和列表生成式生成结果的方式一样。如果想将上边函数改成生成器的生成模式,还需要用到关键字yield
def fib(times):
n = 0
a,b = 0,1
while n<times:
yield b
a,b = b,a+b
n+=1
return 'done'
F = fib(5)
print(next(F))
print(next(F))
print(next(F))
迭代器
迭代是访问集合元素的⼀种方式。迭代器是⼀个可以记住遍历位置的对象。
迭代器对象从集合的第⼀个元素开始访问,直到所有的元素被访问完结束,只能往前不能后退
1.可迭代对象
能直接使用for循环进行迭代的数据类型有以下几种:
1)集合数据类型
如 list 、 tuple 、 dict 、 set 、 str 等
2)生成器
包括表达式类型的生成器和函数类型的生成器
这些可以直接使用for循环的对象统称为可迭代对象–Iterable
2.能否迭代的判断
使⽤isinstance()
函数判断⼀个对象是否是Iterable 对象
#使用isinstance()函数前要先导入模块
from collections import Iterable
#调用isinstance()函数
print(isinstance(‘abc’, Iterable))
print(isinstance((x for x in range(10)), Iterable))
运行结果:
3.iter()
函数
可以使用for循环的对象都是Iterable类型;可以使用next()函数的对象都是Iterator类型,Iterator类型是Iterable类型得一部分
可以使用iter()
函数将一个Iterable对象转化为Iterator对象
#运行结果为true
isinstance(iter('abc'), Iterator)