I don't think that's what's happening. In your example with the generator expression, you're calling each lambda as you iterate through the generator, which due to the lazy evaluation of the generator means that the value of the single i variable shared across all each lambda is still only the latest value reached.
If you instead fully evaluate the generator expression before calling any of the functions (for example, by passing it to the list constructor), you get the same behavior as the list comprehension case:
>>> [f() for f in list(lambda: i for i in range(0, 10))]
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]