我有一个多处理脚本,它像这样循环遍历字典:
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
中的键是整数(因此可用于索引作业列表)。但是后来我想到,也许所得到的工作清单不一定按相同的顺序排列(创建时)-这是真的吗? (我希望订单会变得混乱,因为一个过程可能比另一个过程更快完成)
因此,我决定将
key
的datadict
传递给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/