[Python-ideas] Map-then-filter in comprehensions

Michał Żukowski thektulu.pp at gmail.com
Thu Mar 10 17:20:21 EST 2016


Some time ago I was trying to solve the same issue but using a new keyword
"where", and I thought that new keyword is too much for just list
comprehension filtering, so I've made it something like assignments in
expresion, eg.

(x+y)**2 + (x-y)**2 where x=1, y=2

So for list comprehension I can write:

[stripped for line in lines if stripped where stripped=line.strip()]

or:

result = map(f, objs) where f=lambda x: x.return_something()

or:

it = iter(lines)
while len(line) > 4 where line=next(it, '').strip():
    print(line)

or:

lambda x, y: (
    0 if z == 0 else
    1 if z > 0 else
    -1) where z = x + y

or even:

lambda something: d where (d, _)=something, d['a']=1

I even implemented it:
https://github.com/thektulu/cpython/commit/9e669d63d292a639eb6ba2ecea3ed2c0c23f2636

and it works nicely. I was thinking to reuse "with [expr] as [var]" but I
also don't like idea of context sensitive semantics, and I even thought
that maybe someone, someday would want to write "content = fp.read() with
open('foo.txt') as fp"...

The "where" keyword is from guards pattern in Haskell :)

2016-03-10 17:53 GMT+01:00 Pavol Lisy <pavol.lisy at gmail.com>:

> 2016-03-09 6:16 GMT+01:00, Sjoerd Job Postmus <sjoerdjob at sjec.nl>:
> [...]
> > Trying to word it in such a way:
> >
> > "... considering each of the `for` or `if` clauses a block, nesting from
> > left to right, and evaluating the expression to produce an element each
> > time the innermost block is reached. The `with expr as target` should be
> > considered equivalent to `target = expr`.
> >
> > (And here we already see the downside of this idea). Normally a
> > comprehension of the form
> >
> >     (expr1 for target1 in expr2 for target2 in expr3 if expr4)
> >
> > boils down to
> >
> >     for target1 in expr2:
> >         for target2 in expr3:
> >             if expr4:
> >                 yield expr1
> >
> > The natural extension would be for
> >
> >     (expr1 for target1 in expr2 with expr3 as target2 if expr4)
> >
> > to reduce as follows.
> >
> >     for target1 in expr2:
> >         with expr3 as target2:
> >             if expr4:
> >                 yield expr1
> >
> > Instead, it becomes
> >
> >     for target1 in expr2:
> >         target2 = expr3:
> >         if expr4:
> >             yield expr1
> >
> > But of course we're not going to have context managers in
> > comprehensions, are we? So this inconsistency is somewhat forgiveable.
>
> If we want variable assignment we have already "for var in [expr]" syntax.
>
> We could discuss if "with expr as var" syntax is more beautiful. (or
> if it not against There should be one-- and preferably only one
> --obvious way to do it.)
>
> But why omit context manager semantics in "with expr as var" assignment
> syntax?
>
> I personally don't like idea that semantics could be context sensitive
> in this way. (and we could already do pretty complex things in
> comprehension)
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160310/3f1fbee9/attachment.html>


More information about the Python-ideas mailing list