python中既然生成器表达式比列表解析快?那为什么不全部使用生成器表达式?
黄舟
黄舟 2017-04-18 09:16:36
[Python讨论组]

python中既然生成器表达式比列表解析快?那为什么不全部使用生成器表达式?

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

全部回复(4)
怪我咯

generator 的 lazy evaluation (惰性求值) 當然是能盡量用就盡量用, 但有的時候這是不太有意義的, 比如說:

  1. 最後你還是要一個列表

  2. 你需要排序

關於第一點很好明白, 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) 用在:

  1. 追求效率所以希望使用惰性求值, on-the-fly 的 evaluate, 省空間也避免一口氣過多求值

  2. 對於無限無窮的 iteration, 一般的 iterables 是辦不到的

  3. generator 可以憑空生出值來, 一般的 iterator 不行 (generator 也是 iterator)

關於 2, 3 兩點我覺得比較不適用在 generator expression 上面, generator expression 我想最大的用途就在於上述的第一點!

撇開這三點, 使用 list 可能是比較簡單的, 但 如果是 list comprehension 跟 generator expression 比 , 那我覺得只需要考慮第一點的情況來決定就好。

觀念澄清一下:

generator 是 iterator, 反之不一定, iterator 是 iterables, 反之不一定


我回答過的問題: Python-QA

黄舟

生成器表达式实际上是一个生成器,只能迭代一次;而列表解析器生成的列表能多次迭代

天蓬老师

各有各的用处,不能一概而论吧,而且,生成器无法随机访问啊。

PHP中文网

生成器用完就没了,列表可以重复使用。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号