列表生成器
列表生成式即List Comprehensions,是Python內(nèi)置的非常簡(jiǎn)單卻強(qiáng)大的可以用來(lái)創(chuàng)建list的生成式。
>>> range(1, 10)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [x * x for x in range(1,11) if x % 2 == 0]
[4, 16, 36, 64, 100]
>>> li = ['Hello', 'World']
>>> [s.lower() for s in li ]
['hello', 'world']
>>> d = {'x':'A', 'y':'B', 'z':'C'}
>>> [k + '=' + v for k,v in d.iteritems()]
['y=B', 'x=A', 'z=C']
#其他示例
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
#例如,列出當(dāng)前目錄下的所有文件和目錄名
>>> import os # 導(dǎo)入os模塊,模塊的概念后面講到
>>> [d for d in os.listdir('.')] # os.listdir可以列出文件和目錄
生成器
為了解決生成大量元素列表造成的內(nèi)存浪費(fèi),在Python中,有一種一邊循環(huán)一邊計(jì)算的機(jī)制,稱為生成器(Generator)。
生成器創(chuàng)建方法
只要把一個(gè)列表生成式的[]改成(),就創(chuàng)建了一個(gè)generator。
#list
>>> g = [x * x for x in range(10)]
>>> g
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
#generator
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x10dc2abe0>
#訪問(wèn)generator
>>> for n in g:
... print n
#也可用generator.next()訪問(wèn)其元素
yield命令
#斐波拉契數(shù)列 函數(shù)
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print b
a, b = b, a + b
n = n + 1
#把如上fib函數(shù)轉(zhuǎn)的為generator,只需要把print改為yield
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
函數(shù)是順序執(zhí)行,遇到return語(yǔ)句或者最后一行函數(shù)語(yǔ)句就返回。而變成generator的函數(shù),在每次調(diào)用next()的時(shí)候執(zhí)行,遇到y(tǒng)ield語(yǔ)句返回,再次執(zhí)行時(shí)從上次返回的yield語(yǔ)句處繼續(xù)執(zhí)行。
>>> def odd():
... print 'step 1'
... yield 1
... print 'step 2'
... yield 3
... print 'step 3'
... yield 5
...
>>> o = odd()
>>> o.next()
step 1
1
>>> o.next()
step 2
3
>>> o.next()
step 3
5
>>> o.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
總結(jié)
generator是非常強(qiáng)大的工具,在Python中,可以簡(jiǎn)單地把列表生成式改成generator,也可以通過(guò)函數(shù)實(shí)現(xiàn)復(fù)雜邏輯的generator。
要理解generator的工作原理,它是在for循環(huán)的過(guò)程中不斷計(jì)算出下一個(gè)元素,并在適當(dāng)?shù)臈l件結(jié)束for循環(huán)。對(duì)于函數(shù)改成的generator來(lái)說(shuō),遇到return語(yǔ)句或者執(zhí)行到函數(shù)體最后一行語(yǔ)句,就是結(jié)束generator的指令,for循環(huán)隨之結(jié)束。