我有一个多处理脚本,它像这样循环遍历字典:
jobs = []
for key, val in datadict.items():
jobs.append(pool.apply_async(worker, (val))
pool.close()
pool.join()
jobs
是一个结果对象列表,(调用 get()
将给出一个数据列表)
我想格式化结果,使它们成为具有与输入字典相同的键和顺序的字典。
我想在所有工作完成后简单地执行此操作:
result = {key: jobs[key].get() for key, val in datadict}
之所以可行,是因为 datadict
中的键是整数(因此可用于索引作业列表)。
但后来我想到,也许生成的工作列表不一定按照相同的顺序(因为它被创建) - 这是真的吗? (我预计订单可能会变得困惑,因为一个过程可能比另一个过程完成得更快等)
所以我决定将 datadict
的 key
传递给 worker 函数,然后简单地将其作为元组返回。这样调用 jobs[index].get()
将返回一个元组,其中第一个值是键(刚刚通过函数),第二个值是实际结果
然后我可以像这样创建一个字典:
result = dict([job.get() for job in jobs])
所以最终的脚本是:
def worker(val, key):
res = "Do something to val"
return (key, res)
if __name__ == "__main__":
jobs = []
for key, val in datadict.items():
jobs.append(pool.apply_async(worker, (val, key))
pool.close()
pool.join()
result = dict([job.get() for job in jobs])
但这是最好的方法吗?有几点困扰我:
- 到目前为止,
jobs
列表的结果顺序与输入顺序相匹配 - “通过”函数传递一个值似乎有点傻(即什么也不做)
最佳答案
显式排序 datadict
字典键,并迭代它。
import multiprocessing
def worker(val):
res = "Do something to val {}".format(val)
return res
if __name__ == "__main__":
datadict = {1: 'val1', 2: 'val2', 0: 'val0'}
jobs = []
pool = multiprocessing.Pool()
for key in sorted(datadict): # <------------
jobs.append(pool.apply_async(worker, (datadict[key],)))
pool.close()
pool.join()
result = [job.get() for job in jobs]
print(result)
# ['Do something to val 0', 'Do something to val 1', 'Do something to val 2']
顺便说一句,如果worker
只接受一个参数,你可以使用Pool.map
:
if __name__ == "__main__":
datadict = {1: 'val1', 2: 'val2', 0: 'val0'}
jobs = []
pool = multiprocessing.Pool()
result = pool.map(worker, sorted(datadict)) # <---
pool.close()
pool.join()
关于python - 从多处理中收集结果时确保正确的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22038193/