将pool.starmap()函数与dict上的多个参数一起应用,都作为.starmap()内部的参数传递

时间:2019-06-19 16:39:13

标签: python python-3.x parallel-processing

我目前正在尝试对脚本进行并行处理。以下只是模拟我正在处理的当前脚本。基本上,我想在一个函数和一个字典上调用Pool.starmap()函数。问题是,该函数具有多个参数。我不断收到此错误,

TypeError:read_books()带有4个位置参数,但给出了6个位置

我尝试在pool.starmap(function(arg1,arg2,ar3),dict)中使用所需参数调用函数

import multiprocessing as mp
from itertools import product

# dict - key as string, value as a list

library = {
    'horror': ['Book1', 'book2', 'book3'],
    'thriller': ['book3', 'book4', 'book5'],
    'romance': ['book4', 'book5', 'book6']
}

def read_books(group_friends, library_name, amount_of_hours, key):

    for friend in group_friends:
        print(f"friend {group_friends} visits the library to read {key} books")

    print(f"They are all at the library {library_name} and spend a total of {amount_of_hours} there.")


with mp.Pool(processes=len(library)) as pool:
        results = pool.starmap(read_books, library)

我基本上只想对每个键值对执行read_books函数3次

2 个答案:

答案 0 :(得分:0)

starmap等效于:

def starmap(func, iterable):
    for elem in iterable:
        yield func(*elem)

在您的情况下,iterabledict,因此它会迭代键,并且对于每个键,它会用read_books调用*elem,即每个字符放置一个参数。因此您最终致电,例如:

read_books('r', 'o', 'm', 'a', 'n', 'c', 'e')

library应该是这样的,以便您的代码起作用:

library = [
    ['horror', 'Book1', 'book2', 'book3'],
    ['thriller', 'book3', 'book4', 'book5'],
    ]'romance', 'book4', 'book5', 'book6']
]

您也可以这样做:

pool.starmap(read_books, ((k, *vals) for k, vals in library.items()))

在现代python版本中。

您不能只使用library.items(),因为在这种情况下,starmap仅使用两个参数调用该函数:键和值(恰好是一个列表)。

答案 1 :(得分:0)

感谢所有帮助。对不起,如果我的解释不清楚。

library = [
    (['horror', 'Book1', 'book2', 'book3'], "library 1", 44, "key"),
    (['thriller', 'book3', 'book4', 'book5'], "library 2", 44, "ke6"),
    (['romance', 'book4', 'book5', 'book6'], "library 3, 55, "key3)
]

我错误地传递了迭代器。为了将参数正确地应用于传递到pool.starmap()

的函数中,我不得不将书的列表包装在一个元组中。
with mp.Pool(processes=len(library)) as pool:
    results = pool.starmap(read_books, library)