On 28/02/2018 05:23, Chris Angelico wrote:
If calling `f(x)` is expensive or has side effects, the clean operation of
the list comprehension gets muddled. Using a short-duration name binding
retains the simplicity; while the extra `for` loop does achieve this, it
does so at the cost of dividing the expression visually, putting the named
part at the end of the comprehension instead of the beginning.
Maybe add to last sentence "and of adding (at least conceptually) extra
steps: building a 1-element list, then extracting the first element"
That's precisely the point that Serhiy's optimization is aiming at,
with the intention of making "for x in [expr]" a standard idiom for
list comp assignment. If we assume that this does become standard, it
won't add the extra steps, but it does still push that expression out
to the far end of the comprehension, whereas a named subexpression
places it at first use.
I understand that creating the list could be avoided *at runtime*. My
point was that in trying to *read and understand*
stuff = [[y, y] for x in range(5) for y in [f(x)]]
the brain must follow the creation and unpacking of the list. I.e. this
is an extra cost of this particular construction.
And here's a thought: What are the semantics of
a = (42 as a) # Of course a linter should point this out too
At first I thought this was also a laborious synonym for "a=42". But then I
re-read your statement (the one I described above as crystal-clear) and
realised that its exact wording was even more critical than I had thought:
"the new name binding will shadow the other name from the point where it
is evaluated until the end of the statement"
Note: "until the end of the statement". NOT "until the end of the
expression". The distinction matters.
If we take this as gospel, all this will do is create a temporary variable
"a", assign the value 42 to it twice, then discard it. I.e. it effectively
does nothing, slowly.
Have I understood correctly? Very likely you have considered this and mean
exactly what you say, but I am sure you will understand that I mean no
offence by querying it.
Actually, that's a very good point, and I had to actually go and do
that to confirm. You're correct that the "a =" part is also affected,
but there may be more complicated edge cases.
I have read this thread so far - I can't say I have absorbed and
understood it all, but I am left with a feeling that
Expression-Local-Name-Bindings would be preferable to
Statement-Local-Name_Bindings, so that the temporary variable wouldn't
apply to the LHS in the above example. I realise that this is a vague
statement that needs far more definition, but - hand-waving for now - do
you think it would be difficult to change the implementation accordingly?
Rob Cliffe
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/