[Python-ideas] Assignments in list/generator expressions

Eric Snow ericsnowcurrently at gmail.com
Tue Apr 12 08:51:47 CEST 2011


On Mon, Apr 11, 2011 at 11:47 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:

> On Tue, Apr 12, 2011 at 3:06 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> > ys = [y for x in xs given f(x) if p(x) else g(x) as y]
>
> You know, I may have spoken too soon in saying PEP 3150 couldn't help
> with the list comprehension use case.
>
> def remember(f):
>    """Decorator that remembers result until arguments change"""
>    # Essentially an LRU cache for exactly 1 entry
>    last_args = object(), object()
>    last_result = None
>    @functools.wraps(f)
>    def wrapped(*args, **kwds):
>        nonlocal last_args, last_result
>        if last_args != args, kwds:
>            last_args = args, kwds
>            last_value = f(*args, **kwds)
>        return last_value
>    return wrapped
>
> ys = [y(x) for x in xs if y(x)] given:
>    y = remember(f)
>
> Or for the more complicated case:
>
> ys = [y(x) for x in xs if y(x)] given:
>    @remember
>    def y(x):
>        fx  = f(x)
>        return fx if fx else g(x)
>
> Or even (using the subgenerator approach):
>
> ys = [y for y in all_y if y] given:
>    all_y = (f(x) for x in x)
>
> There are all *sorts* of tricks that open up once you don't even need
> to think about possible impacts on the local namespace.
>
>
Like Georg just said, the given clause seems hard to read.  He was referring
to the embedded clause in the list comprehension.  I kind of feel the same
way about the PEP 3150 syntax.  I remember when I was first exposed to list
comprehensions.  At first it was hard because it was organized differently
from any other Python code.  However, I have adjusted.  Maybe a given clause
would be the same.  I'm just not sure.

That "given" after the expression keeps throwing me off.  It just looks out
of place.  Would something like the following be feasible:

c = sqrt(a*a + b*b) given:
    a = retrieve_a()
    b = retrieve_b()

becomes:

given:
    a = retrieve_a()
    b = retrieve_b()
c = sqrt(a*a + b*b)

where the given statement is effectively _decorating_ the simple statement?
 Unfortunately I am not familiar enough yet with the compiler to know what
such decoration would entail, much less if it would be entirely too
complicated.  However, I wanted to throw out there an alternative that is
maybe more readable.  It's also one I would probably find more usable for
plugging in given blocks or disabling them, much like with decorators.

I know this throws off the approach the PEP takes, but I am trying to wrap
my head around how I would use statement local namespaces.  I like how it
cleans up from the namespace those bits that only matter to the target
statement.  It does make it easier to follow to whom those statements in the
given block belong.  Anyway, this has certainly been an enlightening
discussion.  I hope it bears fruit.

-eric

Cheers,
> Nick.
>
> --
> Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20110412/987229e4/attachment.html>


More information about the Python-ideas mailing list