如何立即打印 Python ThreadPoolExecutor.map 的结果?

AKG*_*AKG 4 python map threadpool concurrent-programming concurrent.futures

我正在为多组可迭代对象运行一个函数,在所有进程完成后立即返回所有结果的列表。

def fct(variable1, variable2):

   # do an operation that does not necessarily take the same amount of
   # time for different input variables and yields result1 and result2

   return result1, result2

variables1 = [1,2,3,4]
variables2 = [7,8,9,0]

with ThreadPoolExecutor(max_workers = 8) as executor:
    future = executor.map(fct,variables1,variables2)
    print '[%s]' % ', '.join(map(str, future))
Run Code Online (Sandbox Code Playgroud)
>>> [ (12,3) , (13,4) , (14,5) , (15,6) ]
Run Code Online (Sandbox Code Playgroud)

如何在计算结果后立即打印中间结果,例如变量 1 = 1、变量 2 = 7?

Col*_*Two 5

map已经这样做了,但join需要消耗整个可迭代对象才能创建连接的字符串。将此更改为for循环将使您可以增量打印它:

for i in executor.map(fct, v1, v2):
    print(str(i))
Run Code Online (Sandbox Code Playgroud)

保持与join代码相同的输出需要更多的工作,但无论如何都是可行的:

first = True
print("[ ", end="")
for i in executor.map(fct, v1, v2):
    if first:
        first = False
    else:
        print(" , ", end="")

    print(str(i), end="")
print("]", end="")
Run Code Online (Sandbox Code Playgroud)


dan*_*ano 5

如果您想在结果完成时使用它们而不保留原始迭代的顺序,您可以使用executor.submitwith concurrent.futures.as_completed

from concurrent.futures import ThreadPoolExecutor, as_completed
import time
import random

def fct(variable1, variable2):
   time.sleep(random.randint(1,5))
   return variable1+1, variable2+1

variables1 = [1,2,3,4]
variables2 = [7,8,9,0]

with ThreadPoolExecutor(max_workers = 8) as executor:
    for out in as_completed([executor.submit(fct,*vars) 
                                for vars in zip(variables1, variables2)]):
        print(out.result())
Run Code Online (Sandbox Code Playgroud)

输出(尽管在任何给定的运行中任何顺序都是可能的,由于random.randint):

(4, 10)
(5, 1)
(2, 8)
(3, 9)
Run Code Online (Sandbox Code Playgroud)

as_completedFuture一旦它Future被标记为完成,就会从它的输入列表中产生一个,不管它实际上在输入列表中的哪个位置。这样,如果第二项在 2 秒后完成,但第一项需要 15 秒,您将在两秒后看到第二项的结果,而不需要等待 15 秒。这可能是也可能不是理想的行为,具体取决于您的特定用例。

编辑:

请注意,您仍然可以通过这种方式以原始顺序获得输出。您只需要保存您提供给的列表as_completed

with ThreadPoolExecutor(max_workers = 8) as executor:
    jobs = [executor.submit(fct, *vars) 
               for vars in zip(variables1, variables2)]

    for out in as_completed(jobs):
        print(out.result())
    results = [r.result() for r in jobs]
    print(results)
Run Code Online (Sandbox Code Playgroud)

输出:

(5, 1)
(2, 8)
(3, 9)
(4, 10)
[(2, 8), (3, 9), (4, 10), (5, 1)]
Run Code Online (Sandbox Code Playgroud)