Search code examples
pythonthreadpoolexecutor

How to keep the original order of input when using ThreadPoolExecutor?


from concurrent.futures import ThreadPoolExecutor, as_completed

def add_one(number, n):
    return number + 1 + n

def process():
    all_numbers = []
    for i in range(0, 10):
        all_numbers.append(i)

    threads = []
    all_results = []
    with ThreadPoolExecutor(max_workers=10) as executor:
        for number in all_numbers:
            threads.append(executor.submit(add_one, number))

        for index, task in enumerate(as_completed(threads)):
            result = task.result()
            #print(result)
            all_results.append(result)

    for index, result in enumerate(all_results):
        print(result)

process()

If I set max_works=1, it will print out from 1 to 10 in order; if I set max_workers = 10, the order could be random:

5
3
10
7
1
8
6
2
4
9

How to keep the original order of the input when using ThreadPoolExecutor to process a list of items as in this example?


Solution

  • You can use the map method of the ThreadExecutor:

    from concurrent.futures import ThreadPoolExecutor, as_completed
    
    def add_one(number):
        return number + 1
    
    def process():
        all_numbers = []
        for i in range(0, 10):
            all_numbers.append(i)
    
        all_results = []
        with ThreadPoolExecutor(max_workers=10) as executor:
            for i in executor.map(add_one, all_numbers):
                print(i)
                all_results.append(i)
    
        for index, result in enumerate(all_results):
            print(result)
    
    process()
    

    Updated answer based on comments requirements:

    from concurrent.futures import ThreadPoolExecutor, as_completed
    
    def add_one(args):
        return args[0] + 1 + args[1]
    
    def process():
        all_numbers = []
        for i in range(0, 10):
            all_numbers.append([i, 2])
    
        all_results = []
        with ThreadPoolExecutor(max_workers=10) as executor:
            for i in executor.map(add_one, all_numbers):
                print(i)
                all_results.append(i)
    
        for index, result in enumerate(all_results):
            print(result)
    
    process()