
On Mon, May 3, 2021 at 8:03 PM Jonathan Fine <jfine2358@gmail.com> wrote:
Difference. >>> tmp = (x*x for x in range(5)) ; list(tmp) [0, 1, 4, 9, 16] >>> tmp = (x*x for x in range(5)) ; [ tmp ] [<generator object <genexpr> at 0x7fec02319678>]
Closer parallel:
tmp = (x*x for x in range(5)) ; [ *tmp ] [0, 1, 4, 9, 16]
My understanding of the situation is that the list comprehension [ x*x for x in range(5) ] is a shorthand for list( x*x for x in range(5) ).
Sorta-kinda. It's not a shorthand in the sense that you can't simply replace one with the other, but they do have very similar behaviour, yes. A genexp is far more flexible than a list comp, so the compiled bytecode for list(genexp) has to go to a lot of unnecessary work to permit that flexibility, whereas the list comp can simplify things down. That said, I think the only way you'd actually detect a behavioural difference is if the name "list" has been rebound. But your main point (about str(x) not iterating) is absolutely correct. Perhaps, if Python were being started fresh right now, str(x) would have different behaviour, and the behaviour of "turn anything into a string" would be done by format(), but as it is, str(x) needs to come up with a string representation for x, without iterating over it (which might be impossible - consider an infinite generator). ChrisA