python将地图转换为列表需要很长时间

时间:2015-10-08 19:07:14

标签: python python-3.x

编辑:我使用的是Python 3.5.0,因此map()将返回迭代器而不是list,这与Python 2.x不同

我有一个单元列表,我在所有这些单元上调用REST api来返回有关它们的更多数据。我使用map()来执行此操作,但是当我尝试将该地图转换为列表时,程序会挂起并且不会继续(当我运行它并调试它时)

data = list(map(lambda product: client.request(units_url + "/" + product), units))

起初我认为这可能是一个很快调用api的问题,但是当我手动遍历地图(不将其转换为列表)并打印时,它就可以了:

data = map(lambda product: client.request(units_url + "/" + product), units)
for item in data:
    print(item)    # <-- this works just fine for the entire map

任何人都知道我为什么会这样做?

2 个答案:

答案 0 :(得分:2)

当你list - 如果是map时,这意味着每个请求都是按顺序发送的,等待完成,然后存储到生成的list。如果您要分派1000个请求,这意味着每个请求必须在list构建之前逐个完成,并且您会看到第一个结果;它是完全同步的。

您可以在直接map迭代案例中立即获得结果(几乎),因为它一次只生成一个请求;而不是等待1000个请求,它等待1,你处理该结果,然后等待另一个,等等。

如果目标是最小化延迟,请查看multiprocessing.Pool.imap(或multiprocessing.dummy中实现的池的基于线程的版本;线程可以是并行网络I / O请求的理想选择并赢得& #39; t要求IPC的酸洗数据)。使用Pool的{​​{1}},mapimap方法(根据您的需要选择一种方法),将异步调度请求,其中几个时间(取决于您选择的工人数量)。如果您绝对必须拥有imap_unorderedlist通常会更快地构建它;如果您可以直接进行迭代并且不关心结果的排序,Pool.map将以工作人员可以获得的结果尽可能快地获得结果,无论他们满意的顺序如何。Pool.imap_unordered没有map没有获得任何神奇的性能优势(列表理解通常会更快地运行),所以使用Pool

最快结果的简单示例代码:

Pool

如果您确实需要,可以使用import multiprocessing.dummy as multiprocessing # Import thread based version of library; for network I/O should work fine with multiprocessing.Pool(8) as pool: # Pool of eight worker threads for item in pool.imap_unordered(lambda product: client.request(units_url + "/" + product), units): print(item) 并存储到真实的Pool.map,并假设您有足够的带宽来运行8个并行请求(或者您配置池的工作人员数量很多) ,应该(大致)将完成list的时间除以8。

答案 1 :(得分:-1)

比以前更好的答案。查看this link。在答案的底部附近,它可以很好地分析你为什么要真正使用列表理解。

data = [client.request(units_url +“/”+ product)for product in units]