Question: I am learning asyncio and there is a problem of running a dependence task concurrently with non-dependence ones. So far I couldn't make it work. This is my code: import asyncio import random def first_execution(choice): if choice==1: print(f"First result {choice}") return choice else: print(f"First result {0}") return 0 async def check_first_execution(result_from_first): # Computationally complex function which take a lot of time to compute await asyncio.sleep(10) print(f"First check of value {result_from_first} complete") async def second_execution(result_from_first): # Moderately complex computation await asyncio.sleep(5) print(f"Second result {result_from_first+1}") return result_from_first+1 async def check_second_execution(result_from_second): # Computationally complex function which take a lot of time to compute await asyncio.sleep(10) print(f"Second check of value {result_from_second} complete") async def third_execution(result_from_first): # Moderately complex computation await asyncio.sleep(5) print(f"Third result {result_from_first+2}") return result_from_first+2 async def check_third_execution(result_from_third): # Computationally complex function which take a lot of time to compute await asyncio.sleep(10) print(f"Third check of value {result_from_third} complete") async def main(): choice = random.choice([0, 1]) result_from_first = first_execution(choice) # First part coroutine_1 = check_first_execution(result_from_first) if result_from_first==1: coroutine_2 = second_execution(result_from_first) results = await asyncio.gather(coroutine_1, coroutine_2) elif result_from_first==0: coroutine_3 = third_execution(result_from_first) results = await asyncio.gather(coroutine_1, coroutine_3) # Second part list_results_from_first = [result_from_first+i for i in range(5)] for first_result in list_results_from_first: second_result = await second_execution(first_result) check_second = await check_second_execution(second_result) asyncio.run(main())  In the first part (# First part), my code works but it only runs sequentially, meaning: first_execution -> check_first_execution -> second_execution (with choice==1) :  >> First result 1 >> First check of 1 complete >> Second result 2  whereas, either with choice==1 (or choice==0), I want the check_first_executionand second_execution (or check_first_executionand third_execution) to happen in parallel, for example with choice==1 :  >> First result 1 >> Second result 2 >> First check of 1 complete  The function check_first_execution takes longer to execute so it should finish later than the second_execution function. In the second part (# Second part), it also happened sequentially: second_execution -> check_second_execution -> second_execution -> check_second_execution ..., for example (with choice==1) :  >> Second result 3 >> Second check of 3 complete >> Second result 4 >> Second check of 4 complete >> Second result 5 >> Second check of 5 complete  what I want is something like this: second_execution -> second_execution -> check_second_execution -> second_execution..., example:  >> Second result 3 >> Second result 4 >> Second check 3 complete >> Second result 5 >> Second check 4 complete  How do I achieve the two points above? Any help is appreciated.

Answer: First, when I run your code I get either First result 0 -> Third result 2 -> First check of value 1 complete or First result 1 -> Second result 2 -> First check of value 1 complete depending on the random choice generated, which is my understanding of what you want. So I cannot duplicate what you say is happening as far as the first part is concerned. For the second part it is clear that the statement check_second = await check_second_execution(second_result) cannot be executed until second_result is returned from the statement second_result = await second_execution(first_result). So these two statements must by necessity be executed sequentially. But my understanding is that you want to run 5 instances of these two statement concurrently, one instance for each element of list_results_from_first. If my understanding is correct, the simplest approach is to create a new coroutine run_dependent_coroutines that will run the two sequential coroutines one after another: ... async def main(): ... # Second part async def run_dependent_coroutines(first_result): second_result = await second_execution(first_result) check_second = await check_second_execution(second_result) list_results_from_first = [result_from_first+i for i in range(5)] coroutines = [ run_dependent_coroutines(first_result) for first_result in list_results_from_first ] await asyncio.gather(*coroutines)  Prints: First result 0 Third result 2 First check of value 0 complete Second result 1 Second result 3 Second result 5 Second result 2 Second result 4 Second check of value 1 complete Second check of value 5 complete Second check of value 4 complete Second check of value 3 complete Second check of value 2 complete