[Python-ideas] Temporary variables in comprehensions
Steven D'Aprano
steve at pearwood.info
Thu Feb 15 23:13:41 EST 2018
On Thu, Feb 15, 2018 at 10:13:37AM +0000, Jamie Willis wrote:
> I'm not sure it does indicate a need for refactoring, I'd argue it's quite
> a common pattern, at least in functional languages from which this
> construct arises.
>
> In fact, in those languages, there are laws that govern interactions with
> the comprehensions (though this comes from monads and monads perhaps don't
> quite apply to pythons model). These laws define behaviour that is expected
> equivalent by users;
Python is not a functional language, and the usual Pythonic solution to
an overly complex or inefficient functional expression is to refactor
into non-functional style.
In my experience, most Python users have never even heard of monads, and
those who have, few grok them. (I know I don't.)
> [x for x in xs] = xs
> [f(x) for x in [x]] = f(x)
> [g(y) for y in [f(x) for x in xs]] = [g(y) for x in xs for y in f(x)]
I think these should be:
[x for x in xs] = list(xs) # not to be confused with [x]
[f(x) for x in [x]] = [f(x)]
[g(y) for y in [f(x) for x in xs]] = [g(y) for x in xs for y in [f(x)]]
> Even though that last law isn't completely analogous to the given example
> from the OP,
It can be used though. He has:
[f(x) + g(f(x)) for x in xs]
which can be written as
[y + g(y) for x in xs for y in [f(x)]]
Here's an example:
# calls ord() twice for each x
py> [ord(x) + ord(x)**2 for x in "abc"]
[9506, 9702, 9900]
# calls ord() once for each x
py> [y + y**2 for x in "abc" for y in [ord(x)]]
[9506, 9702, 9900]
And one last version:
py> [y + y**2 for y in [ord(x) for x in "abc"]]
[9506, 9702, 9900]
In production, I'd change the last example to use a generator
comprehension.
> the transformation he wants to be able to do does arise from
> the laws. So it could be argued that not being able to flatten the
> comprehension down via law 3 is unexpected behaviour
Law 3 does apply, and I'm not sure what you mean by the statement that
we can't flatten the comprehension down.
--
Steve
More information about the Python-ideas
mailing list