今天再看Python学习手册20章的时候,再一次学习了迭代对象中的生成器,所谓的生成器,就是一个函数,函数中包含yeild关键字,或者一个类似于(x for x in range(10))这样的生成器表达式
生成器函数:
# -*- coding: utf-8 -*-
def fun():
for i in range(10000):
yield i*2
a = fun()
print a
结果:
C:\Python27\python.exe C:/python_prac/Script/pickledb_prac.py
<generator object fun at 0x00000000032E6A68>
这就说明我们写的这个函数就是一个生成器函数,
生成器表达式:
# -*- coding: utf-8 -*-
a = (x for x in range(10000))
print a
结果:
C:\Python27\python.exe C:/python_prac/Script/pickledb_prac.py
<generator object <genexpr> at 0x00000000030B6A20>
这两种结果是一样的,都会产生一个生成器,它的作用是在产生一个比较大的数据,但是我们不能马上全部产生(内存限制),所以生成器就可以按需生成,它会记录相应的代码位置和局部变量,然后按需求返回相应的值
单迭代对象:
生成器返回的都是单迭代对象,就是只能遍历一次,代码如下:
a = (x for x in range(10000))
aa, bb = iter(a), iter(a)
print aa.next()
print aa.next()
print bb.next()
结果:
C:\Python27\python.exe C:/python_prac/Script/pickledb_prac.py
0
1
2
bb.next()值为2说明aa和bb是一个iter,这就是单迭代对象
多迭代对象
# -*- coding: utf-8 -*-
a= range(10000)
aa, bb = iter(a), iter(a)
print aa.next()
print aa.next()
print bb.next()
结果:
0
1
0
这里bb.next()值为0说明bb是一个新的迭代器,从头开始。
这里的原因时,生成器返回的时它本身,而支持多次迭代的对象返回的是一个辅助类对象而不是它们本身。
这里在对最后一句话做一下解释:
# -*- coding: utf-8 -*-
a = (x for x in range(10000))
print a == iter(a)
输出:
C:\Python27\python.exe C:/python_prac/Script/pickledb_prac.py
True
说明生成器表达式以及生成器函数本省就会返回一个迭代器
总结:至于迭代器和生成器的关系,就一句话,生成器是属于迭代器的一种,只不过它的表现形式更简单,python解释器已经为我们做了迭代器要做的事情(next,__iter__的实现),单迭代对象就是指的时没有实现返回一个辅助类对象的迭代器。