[Python-Dev] The `for y in [x]` idiom in comprehensions
Rob Cliffe
rob.cliffe at btinternet.com
Mon Feb 26 13:41:29 EST 2018
On 22/02/2018 19:04, Serhiy Storchaka wrote:
> Yet one discussion about reusing common subexpressions in
> comprehensions took place last week on the Python-ideas maillist (see
> topic "Temporary variables in comprehensions" [1]). The problem is
> that in comprehension like `[f(x) + g(f(x)) for x in range(10)]` the
> subexpression `f(x)` is evaluated twice. In normal loop you can
> introduce a temporary variable for `f(x)`. The OP wanted to add a
> special syntax for introducing temporary variables in comprehensions.
> This idea already was discussed multiple times in the past.
>
> There are several ways of resolving this problem with existing syntax.
>
> [snip]
>
>
> Stephan Houben proposed an idiom which looks similar to new hypothetic
> syntax:
>
> result = [y + g(y) for x in range(10) for y in [f(x)]]
>
> `for y in [expr]` in a comprehension means just assigning expr to y. I
> never seen this idiom before, but it can be a good replacement for a
> hypothetic syntax for assignment in comprehensions. It changes the
> original comprehension less than other approaches, just adds yet one
> element in a sequence of for-s and if-s. I think that after using it
> more widely it will become pretty idiomatic.
>
> I have created a patch that optimizes this idiom, making it as fast as
> a normal assignment. [2] Yury suggested to ask Guido on the mailing
> list if he agrees that this language patten is worth
> optimizing/promoting.
>
Here's a thought: allow the syntax
for VAR = EXPR
to define a for-loop that is executed exactly once (both inside and
outside comprehensions), i.e. pretty much a synonym for
for VAR in [ EXPR ]
for VAR in ( EXPR , )
especially if Serhiy's optimisation means that the list/tuple is not
actually constructed in the latter.
Pros:
(1) Stephan Houben's example could be written as
result = [y + g(y) for x in range(10) for y = f(x)]
which I find more readable.
(2) Code such as
for i in xrange(10):
could be changed on the fly to:
for i = 1:
I see this as especially useful in debugging, where you want to
limit the program execution to a known problematic bit.
But it some contexts it could be good style.
(3) Preserves the compatibility between a list comprehension and its
"expansion" into for-loops.
(4) Backward compatible, since it is currently illegal syntax
(5) No extra keyword needed
(6) It goes some way towards providing the functionality of
with VAR as EXPR
that has been discussed multiple times.
Best wishes
Rob Cliffe
More information about the Python-Dev
mailing list