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