Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idiomatically gather results from a dict of futures

Tags:

I'm trying to write something as idiomatic as possible to gather results from futures stored in a dict.

Let's imagine I have the following code:

import asyncio

async def sleep(seconds):
    print(f'sleeping for {seconds} seconds')
    await asyncio.sleep(seconds)
    print(f'finished sleeping {seconds} seconds')


async def run():
    tasks = {
        '4': sleep(4),
        '3': sleep(3),
        '2': sleep(2),
        '1': sleep(1),
    }
    print(await gather_from_dict(tasks))


if __name__ == '__main__':
     asyncio.get_event_loop().run_until_complete(run())

The output I'm expecting is:

sleeping for 2 seconds
sleeping for 1 seconds
sleeping for 4 seconds
sleeping for 3 seconds
finished sleeping 1 seconds
finished sleeping 2 seconds
finished sleeping 3 seconds
finished sleeping 4 seconds
{'4': None, '3': None, '2': None, '1': None}

So far the cleanest solution I've found is:

async def gather_from_dict(tasks:Dict[Hashable, Awaitable],
                           loop=None, return_exceptions=False) -> Dict:

    results = await asyncio.gather(
        *tasks.values(),
        loop=loop,
        return_exceptions=return_exceptions
    )
    return dict(zip(tasks.keys(), results))

Any ideas on how to do this in a simpler way? Thanks!!!

like image 378
jordixou Avatar asked Jan 08 '18 13:01

jordixou


People also ask

Does Python iterate dictionary in order?

With Python 3.7, a dictionary is guaranteed to be iterated in the insertion order of keys. If you need to iterate over a dictionary in sorted order of its keys or values, you can pass the dictionary's entries to the sorted() function, which returns a list of tuples.

Is Python dictionary order guaranteed?

Dictionary iteration order happens to be in order of insertion in CPython implementation, but it is not a documented guarantee of the language.

How do you check if a value is in a dictionary?

Check if Variable is a Dictionary with is Operator We can use the is operator with the result of a type() call with a variable and the dict class. It will output True only if the type() points to the same memory location as the dict class. Otherwise, it will output False .

Is a dictionary Python?

Dictionaries are used to store data values in key:value pairs. A dictionary is a collection which is ordered*, changeable and do not allow duplicates. As of Python version 3.7, dictionaries are ordered. In Python 3.6 and earlier, dictionaries are unordered.


1 Answers

I redefined your tasks to make it purer as coroutine lists, and prefer to get the results from the run_until_complete methods, codes like the following, and notice that I return something in your sleep codes, in your codes, you actually return None.

import asyncio


async def sleep(seconds):
    print('sleeping for {seconds} seconds'.format(seconds=seconds))
    await asyncio.sleep(seconds)
    print('finished sleeping {seconds} seconds'.format(seconds=seconds))
    return {seconds: 'value of {seconds}'.format(seconds=seconds)}


if __name__ == '__main__':

    loop = asyncio.get_event_loop()

    tasks = [sleep(i) for i in range(1, 5)]

    finished, _ = loop.run_until_complete(
        asyncio.wait(tasks))

    result = {}

    for task in finished:
        result.update(task.result())

    print(result)
    loop.close()
like image 57
Menglong Li Avatar answered Sep 18 '22 19:09

Menglong Li