How to sort sequence based on a coroutine?

With a naive implementation like:

import asyncio

async def get_priority(value):
    # Simulate sending out network request.
    await asyncio.sleep(0.5)
    return value

values = [1, 2, 3]
sorted_values = await sorted(values, key=get_priority)

(assume that the top-level await was wrapped in an async def)

sorted assumes that the key function is synchronous, and it will try to compare the coroutines themselves instead of the underlying values, leading to a TypeError.

How can I sort a sequence when I want the key function to be a coroutine? I could write the sorted implementation myself, but specifically wondering if I can somehow extract the asynchronous key computations outside of sorted using asyncio, so I can stick to standard lib.

Answer

Ended up stumbling upon Implement async/await in sort function of arrays javascript, which referenced a Schwartzian transform, where the priorities to sort the values by are precomputed and stored alongside the original values. Below is an implementation in Python:

import asyncio
from operator import itemgetter

async def get_priority(value):
    # Simulate sending out network request.
    await asyncio.sleep(0.5)
    return value

values = [1, 2, 3]
value_priorities = await asyncio.gather(*map(get_priority, values))
sorted_values = [value for value, _ in sorted(
    zip(values, value_priorities),
    key=itemgetter(1)
)]