If I have understood correctly how the concurrent.futures module in Python 3 works, the following code:
import concurrent.futures
import threading
# Simple function returning a value
def test(i): a = 'Hello World\n' return a
def main(): output1 = list() with concurrent.futures.ThreadPoolExecutor() as executor: # psdd iterator to test function for out1 in executor.map(test, range(0, 10)): # append returned result output1.append(out1) # confirm output print(output1) print("Task Executed {}".format(threading.current_thread()))
if __name__ == '__main__': main()...performs the following functions:
- Passes a for loop to the function called
test(). - Processes the loop in parallel, rather than in serial.
However, what I really want is to process the loop in parallel in my main() function as so:
import concurrent.futures
import threading
def main(): output1 = list() with concurrent.futures.ThreadPoolExecutor() as executor: # psdd iterator to test function for out1 in executor.submit(range(0, 10)): a = 'Hello World\n' # append returned result output1.append(a) # confirm output print(output1) print("Task Executed {}".format(threading.current_thread()))
if __name__ == '__main__': main()...this however produces the following error:
Traceback (most recent call last): File "G:\HTPC Scripts\WebGrab Plus\TESTTESTTEST2.py", line 221, in <module> main() File "G:\HTPC Scripts\WebGrab Plus\TESTTESTTEST2.py", line 209, in main for out1 in executor.submit(range(0, 10)):
TypeError: 'Future' object is not iterableWhat do I need to amend in my code?
Thanks
41 Answer
It doesn't matter whether you use submit or map, you always have to use a callable (such as a function) as the first argument.
Python does allow nested functions (also take note of the way to use Futures);
import concurrent.futures
def main(): def worker(arg): return str(arg) + ' Hello World!' with concurrent.futures.ThreadPoolExecutor() as e: fut = [e.submit(worker, i) for i in range(10)] for r in concurrent.futures.as_completed(fut): print(r.result())
if __name__ == '__main__': main()The only way to define a callable in-place is with a lambda expression, but those have significant limitations.