【发布时间】: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:相当大的字典)。
为什么这最后一步要花这么长时间,有没有更快的方法将生成器的输出转换为列表?
是否有可扩展且快速的替代策略?
编辑
作为对 cmets 的回应,我在原帖中添加了其他信息。
【问题讨论】:
-
单个
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]