Python 的 Generator Tricks

Posted by TJ Wei on 星期五, 4月 25, 2008 with No comments

我們都知道 python 的 iterator很有趣,比方下面這個generator 能生成所有質數(根本就只是把質數的定義講一遍而已):

(n for n in itertools.count() if n>1 and not any(n%k==0 for k in range(2,n)))
比較複雜一點的費波納契數列 callable iterator
iter((lambda x:x.append(sum(x)) or x.pop(0)).__get__([1,1]),None)

我們也知道新的 send/yield 能夠玩出不少把戲,不過這篇簡報簡直把 generator 玩得爐火純青 Generator Tricks for System Programming

generator 根本就能夠當成 pipeline 來玩。

比方你有一組 log,最後一個欄位不是數字就是 ' -'(當成 0),你想算這些欄位的總和,原來你可能會寫成

wwwlog = open("access-log")
total = 0
for line in wwwlog:
bytestr = line.rsplit(None,1)[1]
if bytestr != '-':
total += int(bytestr)
print "Total",total
但用 generaotr 來思考
wwwlog = open("access-log")
bytecolumn = (line.rsplit(None,1)[1] for line in wwwlog)
bytes = (int(x) for x in bytecolumn if x != '-')
print "Total", sum(bytes)

優雅多了,而且從 pipeline 來看,反而更容易理解。

配合另外一個也很神的 generator_tools ,就能玩出更多把戲。

Categories: ,