将字典的键和值并行传递给函数?
Posted
技术标签:
【中文标题】将字典的键和值并行传递给函数?【英文标题】:Passing Keys and Values of a Dictionary to a Function in Parallel? 【发布时间】:2021-03-30 19:36:33 【问题描述】:我正在尝试使用多处理模块在 Python 中将字典的键和值并行传递给函数。
我正在并行运行一系列数千个计算,主函数最初采用一个以笛卡尔形式描述分子坐标的数组,然后用它做一些事情。只需通过列表推导将数组列表映射到使用多处理池的函数即可。
def main(grid_point):
do stuff...
if __name__ == "__main__":
grid_points = [] # some list of arrays
run_pool = multiprocessing.Pool()
run_pool.map(main, [grid_point for grid_point in grid_points])
# Works fine
但是,我希望存储一些特定于每个分子坐标的数据,以便在并行计算之前,这些值的存储顺序与它们在列表中的初始索引相对应。请注意,每次计算都不会花费相同的时间来运行,因此我可能会混淆数据。
为了克服这个问题,我希望将字典的每个键:值对并行传递给函数。现在密钥将对应于并行运行之前的原始索引,因此我有办法确保我的数据不会被打乱。
def main(gp_key, grid_point):
do stuff...
if __name__ == "__main__":
grid_points = [] # some list of arrays
grid_points_map = k: v for k, v in enumerate(grid_points) # Dict of indexes and arrays
run_pool = multiprocessing.Pool()
run_pool.map(main, gp_key: grid_point for gp_key, grid_point in grid_points_map)
# Does not work
任何关于如何最好地传递键:并行值对的见解都会有很大帮助,甚至任何关于如何确保最终存储的数据与其原始索引相对应的建议。我能想到的唯一其他方法是使用池将元组传递给函数,即run_pool.map(main, [(k, v) for k, v in enumerate(grid_points)]
,然后将元组解压缩到main()
中的索引和数组中,如index, array = grid_point
。
【问题讨论】:
我认为你的方法看起来不错。当你运行这段代码时会发生什么?你有一个# Does not work
评论,但不要解释这意味着什么。什么不完全有效?您的代码的最终结果是什么?您希望它是什么?
Nitpick:grid_points_map
是多余的。直接使用enumerate(grid_points)
即可。
您错误地使用了map()
。它一次将一个项目从可迭代传递到您的 main()
函数。当您通过字典map()
时,您只能获得密钥。在这种情况下,您可能需要starmap()
而不是map()
。正如我在之前的评论中提到的,您可以直接将其与 enumerate(grid_points)
一起使用。
【参考方案1】:
您错误地使用了run_pool.map()
。当您执行run_pool.map(main, ...)
时,它会将每个元素从可迭代对象传递给函数main()
,一次一个。在字典的情况下,元素是键。因此,您将0
、1
、2
等值传递给main()
,而不是grid_point
值。相反,您想直接对来自enumerate()
的结果使用starmap()
。中间字典不是必需的。
【讨论】:
以上是关于将字典的键和值并行传递给函数?的主要内容,如果未能解决你的问题,请参考以下文章