generator 的 lazy evaluation (惰性求值) 當然是能盡量用就盡量用, 但有的時候這是不太有意義的, 比如說: 最後你還是要一個列表 你需要排序 關於第一點很好明白, generator 只能夠 iterate 卻不具備大部分的 list 能力: >>> I = [5 ,3, 1, 6, 2] >>> genexp = (i for i in I) >>> genexp[0] # generator 不支援 __getitem__ Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'generator' object has no attribute '__getitem__' >>> genexp + [9, 9, 9] # generator 不支援列表串接 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'generator' and 'list' 諸如此類... 那可能觀眾會想問, 那這樣就好了阿: >>> list(genexp) 那這樣子跟直接用 list comprehension 有差嗎? (還真的有差! 你白做工了) 其實第二點跟第一點類似, 不過你可能會想要反駁: >>> sorted(genexp) [1, 2, 3, 5, 6] 這不是好好的嗎? 沒錯, sorted 支援任何 iterables 的輸入, 但是 要排序, 所有的項目都必須要被求值 也就是說, 惰性求值完全沒有派上用場, 這個時候還不如直接用 list 來的乾脆。 最後 @Maslino 有提到一很重要的一點, generator 是會耗盡的, 是一次使用性的, 所以要反覆使用多次的話只能夠依靠 generator function: def gen(): for i in range(10): yield i 或者 return genexp 的 function: def gen(): return (i for i in range(10)) 然後: for i in gen(): print(i) 這樣就可以反覆多次使用了 但這樣做是好還是壞還要看情況而定, 大多數的時候直接用 list 會比較容易 結論 (有點複雜, 如果看不懂可以再討論) generator (這裡指一般的 generator 而非 genexp) 用在: 追求效率所以希望使用惰性求值, on-the-fly 的 evaluate, 省空間也避免一口氣過多求值 對於無限無窮的 iteration, 一般的 iterables 是辦不到的 generator 可以憑空生出值來, 一般的 iterator 不行 (generator 也是 iterator) 關於 2, 3 兩點我覺得比較不適用在 generator expression 上面, generator expression 我想最大的用途就在於上述的第一點! 撇開這三點, 使用 list 可能是比較簡單的, 但 如果是 list comprehension 跟 generator expression 比 , 那我覺得只需要考慮第一點的情況來決定就好。 觀念澄清一下: generator 是 iterator, 反之不一定, iterator 是 iterables, 反之不一定 我回答過的問題: Python-QA
generator 的 lazy evaluation (惰性求值) 當然是能盡量用就盡量用, 但有的時候這是不太有意義的, 比如說:
最後你還是要一個列表
你需要排序
關於第一點很好明白, generator 只能夠 iterate 卻不具備大部分的 list 能力:
諸如此類...
那可能觀眾會想問, 那這樣就好了阿:
那這樣子跟直接用 list comprehension 有差嗎? (還真的有差! 你白做工了)
其實第二點跟第一點類似, 不過你可能會想要反駁:
這不是好好的嗎? 沒錯, sorted 支援任何 iterables 的輸入, 但是
也就是說, 惰性求值完全沒有派上用場, 這個時候還不如直接用 list 來的乾脆。
最後 @Maslino 有提到一很重要的一點, generator 是會耗盡的, 是一次使用性的, 所以要反覆使用多次的話只能夠依靠 generator function:
或者 return genexp 的 function:
然後:
這樣就可以反覆多次使用了
但這樣做是好還是壞還要看情況而定, 大多數的時候直接用 list 會比較容易
結論 (有點複雜, 如果看不懂可以再討論)
generator (這裡指一般的 generator 而非 genexp) 用在:
追求效率所以希望使用惰性求值, on-the-fly 的 evaluate, 省空間也避免一口氣過多求值
對於無限無窮的 iteration, 一般的 iterables 是辦不到的
generator 可以憑空生出值來, 一般的 iterator 不行 (generator 也是 iterator)
關於 2, 3 兩點我覺得比較不適用在 generator expression 上面, generator expression 我想最大的用途就在於上述的第一點!
撇開這三點, 使用 list 可能是比較簡單的, 但 如果是 list comprehension 跟 generator expression 比 , 那我覺得只需要考慮第一點的情況來決定就好。
觀念澄清一下:
我回答過的問題: Python-QA