Playing around with iPython, I was surprised to discover that given a list f
of objects each supporting some method x()
(that, say, prints out "Hi!"
), the expression:
(y.x() for y in f)
is not semantically equivalent to
[y.x() for y in f]
The first one (with the tuple as output) results in a generator expression that is not evaluated unless I iterate over it, whereas the one with the list actually causes the generation to happen immediately:
In [30]: (y.x() for y in f)
Out[30]: <generator object <genexpr> at 0x2d78d70>
but
In [31]: [y.x() for y in f]
Hi!
Hi!
Hi!
Hi!
This seems rather counter-intuitive.
Question: Why is the first expression not generating a tuple of the values obtained from the generator the way the list is being built?
Update: As I stare at this more, I realize that perhaps what's happening in the first case is that Python is just building a tuple containing a generator rather than evaluating the generator as it is in the second case.
So is it true that it is not possible to directly get a tuple as the result of generating a list comprehension? (I understand I can do tuple([y.x() for y in f])
). I don't have a use case, this is purely for my understanding.