Introducing the async keyword in the generator expression makes it become an async generator.
If you are using a recent Ipython as the REPL, when used as a list comprehension, the expression in the inner list is fully resolved.. Ipython special "call async functions in a transparent way" do just that, and all the outer loop "sees" is simply a list.
In normal Python code, or on the "pure" REPL, the async keyword use is restricted to async function bodies, and you'd get a SyntaxError: asynchronous comprehension outside of an asynchronous function error with both snippets anyway.
So, getting back to your problem: introducing an await in the expression in the inner generator, it becomes an asynchronous generator - the outer code will need the inner code to be run on each iteration. But all you need is to use async for to get its values in the outer comprehension:
[x async for x in [(i, await f(i)) for i in l2]]