[Python-Dev] The `for y in [x]` idiom in comprehensions

Serhiy Storchaka storchaka at gmail.com
Thu Feb 22 14:04:24 EST 2018


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.

1. Inner generator expression:

     result = [y + g(y) for y in (f(x) for x in range(10))]

2. The same, but with extracting the inner generator expression as a 
variable:

     f_samples = (f(x) for x in range(10))
     result = [y+g(y) for y in f_samples]

3. Extracting the expression with repeated subexpressions as a function 
with local variables:

     def func(x):
         y = f(x)
         return y + g(y)
     result = [func(x) for x in range(10)]

4. Implementing the whole comprehension as a generator function:

     def gen():
         for x in range(10):
             y = f(x)
             yield y + g(y)
     result = list(gen())

5. Using a normal loop instead of a comprehension:

     result = []
     for x in range(10):
         y = f(x)
         result.append(y + g(y))

And maybe there are other ways.

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.

[1] https://mail.python.org/pipermail/python-ideas/2018-February/048971.html
[2] https://bugs.python.org/issue32856



More information about the Python-Dev mailing list