[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