Python 列表解析list comprehension和生成表達式generator expression


 

如果想通過操作和處理一個序列(或其他的可迭代對象)來創建一個新的列表時可以使用列表解析(List comprehensions)和生成表達式(generator expression)

 

(1)list comprehension

[expr for iter_var in iterable ] or [expr for iter_ in iterable if cond_expr]

 

l1=[1,2,3,4,5]

[x+1 for x in l1]

[2, 3, 4, 5, 6]

[x-1 for x in l1 if x>3]

[3, 4]

dict([(x,x+1) for x in l1])

{1: 2, 2: 3, 3: 4, 4: 5, 5: 6}

vec1=[1,2,3]
vec2=[6,7,8]
sq=[vec1[i]+vec2[i] for i in range(len(vec1))]
print sq

[7, 9, 11]

[x*y for x in [1,2,3] for y in [3,4,5]]

[3, 4, 5, 6, 8, 10, 9, 12, 15]

[(x+y) for x in l1 for y in range(x)]

[1, 2, 3, 3, 4, 5, 4, 5, 6, 7, 5, 6, 7, 8, 9]
def t_f(x): return x+1 [t_f(i) for i in l1] [1, 2, 3, 4, 5] 等價於 map(t_f,l1)

 

(2)generator expression

通過列表生成式,我們可以直接創建一個列表。但是,受到內存限制,列表容量肯定是有限的。而且,創建一個包含100萬個元素的列表,不僅占用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那后面絕大多數元素占用的空間都白白浪費了。所以應當考慮使用生成器表達式而不是列表解析.生成器表達式並不真正創建數字列表, 而是返回一個生成器generator,generator保存的是算法,每次調用next(g),就計算出g的下一個元素的值,直到計算到最后一個元素,沒有更多的元素時,拋出StopIteration的錯誤。但是我們一般通過for循環來迭代它,並且不需要關心StopIteration的錯誤。


for n in g:
print(n)

由於這個生成器在每次計算出一個條目后,把這個條目“產生”(yield)出來。 生成器表達式使用了“惰性計算”(lazy evaluation,也有翻譯為“延遲求值”,我以為這種按需調用call by need的方式翻譯為惰性更好一些),只有在檢索時才被賦值( evaluated),所以在列表比較長的情況下使用內存上更有效.A generator object in python is something like a lazy list. The elements are only evaluated as soon as you iterate over them. 

 

(expr for iter_var in iterable) or (expr for iter_var in interable if cond_expr)

 

ge1=(x+1 for x in l1 if x%2)
ge1

<generator object <genexpr> at 0x000000000959EA68>

type(ge1)

generator

for i in ge1:
    print i

[1, 2, 3, 4, 5]

 

some adds:

1)當需要只是執行一個循環的時候盡量使用循環而不是列表解析,這樣更符合python提倡的直觀性

2)當有內建的操作或者類型能夠以更直接的方式實現的,不要使用列表解析

good:
l2=l1

bad:
l2=[x for x in l1]

3)如果需要對每個元素都調用並且返回結果時,應使用L1=map(f,L), 而不是 L1=[f(x) for x in L]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM