1. 程式人生 > >python中的列表推導與生成器

python中的列表推導與生成器

1.先看兩個列表推導式

def t1():
    func1 = [lambda x: x*i for i in range(10)]
    result1 = [f1(2) for f1 in func1]
    print result1

def t2():
    func2 = [lambda x, i=i: x*i for i in range(10)]
    result2 = [f2(2) for f2 in func2]
    print result2

上面是兩個列表推導式,裡面包含有lambda表示式。輸出結果分別為:

[18, 18, 18, 18, 18, 18
, 18, 18, 18, 18] [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

2.為什麼結果會不同

在上面的例子中,列表解析會生成一系列的函式物件。例如

def func():
    pass

會產生一個名為func的函式物件。注意不同於func(),加上小括號以後,此時變為了呼叫函式物件。

函式物件只有在呼叫的時候才開始對內部的變數進行引用。在t1()方法中,對i來說, 當函式對它引用的時候, 它已經變為9, 所以10個函式都引用了i=9。
而對於t2()方法來說,lambda函式相當於變成接受兩個引數了,所以返回了不一樣的結果。

3.另外的方式

def
t3():
func3 = (lambda x: x*i for i in range(10)) result3 = [f3(2) for f3 in func3] print result3

上面的程式碼,輸出的結果為:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

此時,相當於把列表推導式變成了生成器,結果又不一樣了!
對於生成器, 只有你需要的時候它才會求值, 這也是和列表解析式的區別, 列表解析式只要你執行, 馬上就把i變為了9, 可是生成器不會, 當你呼叫第一個函式的時候, 他把相應的i求出來, 然後停止, 等你下一次呼叫, 這個就完美符合我們的預期了.