Как только вы запускаете задач в отдельных процессах, вы больше не контролируете порядок выполнения, поэтому вы не можете ожидать, что действия этих задач будут выполняться в любом предсказуемом порядке - особенно если задачи могут занимать различную продолжительность.
Если вы распараллеливаете (?) Задачу / функцию с последовательностью аргументов и хотите изменить порядок результатов в соответствии с порядком исходной последовательности, вы можете передать информацию о последовательности в задачу / функцию, которая будетбыть возвращен заданием и может быть использован для восстановления исходного заказа.
Если функция original выглядит следующим образом:
def f(arg):
l,n = arg
#do stuff
time.sleep(random.uniform(.1,10.))
result = f'{l}{n}'
return result
Рефакторинг функции: принять информацию о последовательности и передать ее с возвратомзначение.
def f(arg):
indx, (l,n) = arg
time.sleep(random.uniform(.1,10.))
result = (indx,f'{l}{n}')
return result
enumerate
можно использовать для добавления информации о последовательности в последовательность данных:
originaldata = list(zip('abcdefghijklmnopqrstuvwxyz', range(26)))
dataplus = enumerate(originaldata)
Теперь аргументы имеют вид (index,originalarg)
... (0, ('a',0'), (1, ('b',1))
.
И возвращенные значения из мультипроцессов выглядят так (если собраны в список) -
[(14, 'o14'), (23, 'x23'), (1, 'b1'), (4, 'e4'), (13, 'n13'),...]
, которые легко сортируются по первому элементукаждый результат, key=lambda item: item[0]
, и значения, которые вы действительно хотите получить, выбрав вторые элементы после сортировки results = [item[1] for item in results]
.