Я бы хотел, чтобы concurrent.futures.ProcessPoolExecutor.map()
вызывал функцию, состоящую из 2 или более аргументов. В приведенном ниже примере я прибегал к использованию функции lambda
и определял ref
как массив равного размера numberlist
с одинаковым значением.Как передать функцию с несколькими аргументами на python concurrent.futures.ProcessPoolExecutor.map()?
1-й вопрос: Есть ли лучший способ сделать это? В случае, когда размер списка номеров может составлять от миллиона до миллиарда элементов, следовательно, размер ссылки должен соответствовать списку номеров, этот подход излишне берет драгоценную память, чего я бы хотел избежать. Я сделал это, потому что я прочитал функцию map
, чтобы завершить ее отображение до тех пор, пока не будет достигнут самый короткий конец массива.
import concurrent.futures as cf
nmax = 10
numberlist = range(nmax)
ref = [5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
workers = 3
def _findmatch(listnumber, ref):
print('def _findmatch(listnumber, ref):')
x=''
listnumber=str(listnumber)
ref = str(ref)
print('listnumber = {0} and ref = {1}'.format(listnumber, ref))
if ref in listnumber:
x = listnumber
print('x = {0}'.format(x))
return x
a = map(lambda x, y: _findmatch(x, y), numberlist, ref)
for n in a:
print(n)
if str(ref[0]) in n:
print('match')
with cf.ProcessPoolExecutor(max_workers=workers) as executor:
#for n in executor.map(_findmatch, numberlist):
for n in executor.map(lambda x, y: _findmatch(x, ref), numberlist, ref):
print(type(n))
print(n)
if str(ref[0]) in n:
print('match')
Запуск выше код, я обнаружил, что функция map
удалось добиться моего желаемого результата. Однако, когда я передал те же условия для concurrent.futures.ProcessPoolExecutor.map(), python3.5 неудачу с этой ошибкой:
Traceback (most recent call last):
File "/usr/lib/python3.5/multiprocessing/queues.py", line 241, in _feed
obj = ForkingPickler.dumps(obj)
File "/usr/lib/python3.5/multiprocessing/reduction.py", line 50, in dumps
cls(buf, protocol).dump(obj)
_pickle.PicklingError: Can't pickle <function <lambda> at 0x7fd2a14db0d0>: attribute lookup <lambda> on __main__ failed
Вопрос 2: Почему происходят эта ошибка и как я могу получить одновременно .futures.ProcessPoolExecutor.map() для вызова функции с более чем 1 аргументом?
Вы правы, я прибегал к экспериментированию с lambda, потому что изначально у меня возникла проблема с передачей функции с двумя аргументами в 'executor', когда' ref' был константой. После преобразования 'ref' в список, равный размеру' numberlist', я просто понял, что забыл удалить лямбда. То, что я действительно хотел, было решением, где 'ref' является постоянным или похожим. Таким образом, вспомогательная функция & itertools.repeat', которую вы упомянули, работает. Спасибо. –
Я хотел бы предложить вам ответить на мой [последующий вопрос] (http://stackoverflow.com/q/42074501/5722359), где я сравнивал производительность «Executor.map» с «Executor.submit» и нашел бывший значительно медленнее, и мне нравится знать, почему? –