【问题标题】:Python: Why is converting a generator to a list taking so longPython:为什么将生成器转换为列表需要这么长时间
【发布时间】:2014-02-16 21:00:19
【问题描述】:

在为 API 创建一些 JSON 输出时,我使用生成器来确保转换过程是可扩展的,然后将其输出转换为列表,以便可以将其作为 JSON 列表插入到更大的 JSON 对象中对象(this_list)。

迭代创建生成器足够快 - 100 个项目需要 1-200 毫秒 - 但是将生成器转换为列表大约需要 10 秒:

def create_a_list_of_objects(dataset):

    these_items = (do_some_processing_to_each_item(item) for item in dataset)

    >>> 0.15

    convert_to_list = list(these_items)

    >>> 8.75

    return convert_to_list

json.dumps({

   this_list: create_a_list_of_objects(datset)

})

如果我直接通过列表推导运行它,则大约需要 10 秒才能完成。

return [do_some_processing_to_each_item(item) for item in dataset]

>>> 10.41

如果我把它分解成一个显式循环,那么 do_some_processing_to_each_item 的每次迭代大约需要 0.03 秒,总共大约需要 3 秒(我假设这和列表理解之间的差异是由于输出的大小do_some_processing_to_each_item:相当大的字典)。

为什么这最后一步要花这么长时间,有没有更快的方法将生成器的输出转换为列表?

是否有可扩展且快速的替代策略?

编辑

作为对 cme​​ts 的回应,我在原帖中添加了其他信息。

【问题讨论】:

  • 单个do_some_processsing_to_each_item调用的时间是多少?
  • 你在哪里做“迭代生成器”?在您的代码中,在 list 调用本身之外没有发生此类迭代。到目前为止,您所展示的一切都与 do_some_processing_to_each_item 这很慢的想法不相容。
  • 我不确定您是否了解生成器的工作原理......实际上没有理由在提供的示例代码中使用生成器
  • 可能是 json.dumps 实际上是需要 10 秒的部分吗?如果是这样,那是因为它涉及大量的字符串转换和操作
  • 为什么不直接使用列表组合,比如:return [do_some_processing_to_each_item(item) for item in dataset]

标签: python generator


【解决方案1】:

为什么不直接使用列表组合,比如:

return [do_some_processing_to_each_item(item) for item in dataset]

【讨论】:

  • 虽然这是一个有效的建议,但它不是答案。应该是评论。
  • @user2357112 BDFL 说这可以显着提高速度
【解决方案2】:

在上面的代码中,您没有“遍历生成器”(本质上创建列表时除外),因此除非您单独执行此操作,否则您没有基准。你的生成器表达式

(do_some_processing_to_each_item(item) for item in dataset)

只是创建一个生成器;在调用these_items.__next__() 之前不会进行处理(因为在循环these_items 时对每个项目都是如此)。

要排除列表创建/存储是瓶颈,您可以只计时:

for item in these_items:
    do_some_processing_to_each_item(item)

【讨论】:

  • 非常感谢,我误解了使用生成器时动作发生的位置,即不是在生成器本身的创建中,而是在 list() 中迭代它时。
猜你喜欢
  • 1970-01-01
  • 2016-11-12
  • 2016-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-31
  • 1970-01-01
相关资源
最近更新 更多