[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