1、迭代器
可迭代对象,一般能用在 for … in … 中的对象,都是迭代器。迭代器将所有数据都保存在内存中,比如list。
2、生成器
用法上可以理解为只能迭代一轮的迭代器,不把所有数据都保存在内存中,实时生成数据,节省内存。
如下代码所示,首先定义一个名叫“mygenerator”的生成器。第一轮迭代,顺序输出生成器生成的数据;第二轮迭代,因为数据都已生成,因此没有输出
mygenerator = (x for x in range(3))
print "mygenerator is %s" % mygenerator
# out:
# mygenerator is <generator object <genexpr> at 0x00000000043BDD80>
print "first iteration, output:"
for i in mygenerator:
print i
# out:
# first iteration, output:
# 0
# 1
# 2
print "second iteration, output:"
for i in mygenerator:
print i
# out:
# second iteration, output:
3、yield
yield只能用在函数内部,调用函数后将返回一个生成器。
生成器都有一个next()方法,第一次调用next,相当于启动生成器,会从生成器函数代码的第一行开始执行,一直执行到yield语句,并返回yield后面的值。再次调用next()方法,会从yield后面一条语句开始执行,再次遇到yield停止并返回yield后面的值。
函数内部可以执行几次yield语句,就可以调用几次next方法,即能从该生成器函数获得几次值。
def mygenerator():
print "hi, I'm a mygenerator"
print "yield 1 execute"
yield 1
print "yield 2 exec"
yield 2
print "yield 3 exec"
yield 3
d = mygenerator()
print d
# out:
# generator object mygenerator at 0x000000000347E288>
k = d.next()
# out:
# hi, I'm a mygenerator
# yield 1 execute
print k
# out:
# 1
k = d.next()
# out:
# yield 2 exec
print k
# out:
# 2
k = d.next()
# out:
# yield 3 exec
print k
# out:
# 3
4、yield生成器的send(value) 方法
send(value) 和 next() 功能基本一致,都能获得生成器的下一个值,区别在于send方法同时可以传递一个值到生成器内部。
send(None) 和 next() 作用完全相同。
send()执行时,会先为上一条yield语句的等号左侧赋值(注意等号右侧的yield已经执行过,不会再执行),然后接着执行到下一条yield语句。第一次执行生成器时,由于没有更早的yield语句来赋值,因此只能用send(None)或next方法。
def mygenerator():
print "hi, I'm a mygenerator"
print "yield 1 execute"
value_from_send = yield 1
print "value_from_send is %s" % value_from_send
print "yield 2 exec"
yield 2
d = mygenerator()
k = d.send(None)
# out:
# hi, I'm a mygenerator
# yield 1 execute
print k
# out:
# 1
k = d.send(100)
# out:
# value_from_send is 100
# yield 2 exec
print k
# out:
# 2