Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #54829 > unrolled thread

Re: Proposal: [... for ... while cond(x)]

Started byNick Mellor <thebalancepro@gmail.com>
First post2013-09-26 07:39 -0700
Last post2013-09-26 07:50 -0700
Articles 2 — 1 participant

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Proposal: [... for ... while cond(x)] Nick Mellor <thebalancepro@gmail.com> - 2013-09-26 07:39 -0700
    Re: Proposal: [... for ... while cond(x)] Nick Mellor <thebalancepro@gmail.com> - 2013-09-26 07:50 -0700

#54829 — Re: Proposal: [... for ... while cond(x)]

FromNick Mellor <thebalancepro@gmail.com>
Date2013-09-26 07:39 -0700
SubjectRe: Proposal: [... for ... while cond(x)]
Message-ID<99048467-e7eb-461a-aa9b-e30cf5f6f1c7@googlegroups.com>
Hi all,

It might be a risk that we create some hairy or subtle semantics, but perhaps this idea has legs. The 'pythonic' syntax is very attractive.

# skip the silence at the start
data = (amp for amp in signal from abs(amp) > 0.05)

# drop files that are less than 600 bytes
# (already sorted into ascending order of size)
files = (file for file in filelist from os.stat(file).st_size > 600)

# Analyse bunch of log lines up to a certain timestamp
cutoff = datetime.datetime.now() - datetime.timedelta(hours=1)
checklogs = (entry for entry in log while entry.timestamp <= cutoff)

In use it feels along the same lines as else: clauses in try/finally and for loops, both of which I like-- it seems natural in Python, keeps the meaning clear and consistent, avoids complicated, iterative, inexpressive code.

Terry Reedy wrote:
> You're right. The syntax is ambiguous. I agree it's not a good idea,
now. :)

When while, if and from are made mutually exclusive, not mixed, on a comprehension clause, it looks to me like the ambiguity disappears:

> x for x in xs while cond(x) if blah(x)

not legal Python-- if and while are mutually exclusive on the same comprehension clause. On the one hand it's like writing x for x in xs if f(x) < 10 if g(x) > 100, the illegality of which no-one is complaining about. Just write:

x for x in xs while cond(x) and cond2(x)

or

x for x in xs if cond(x) and cond2(x)

If there is a need to filter using if as well as while, then use two comprehensions:

intermediate = [x for x in xs while cond(x)]
final = [x for x in intermediate if cond2(x)]

or the same comprehension applied to itself:

y for y in x for x in xs if cond(x) while cond2(y)

The if and the while operation *should* be kept separate-- they're different stages of processing the data.

> > x*y for x in xs while cond(x) for y in ys if cond(y)

legal Python-- the 'if cond(y)' unambiguously refers to the inner comprehension. 


> x for x in xs if blah(x) while cond(x)

not legal Python-- if and while are mutually exclusive in the same comprehension clause.

The objection to "while" as an abbreviation:

> e(x) for x in xs if cond(x)
> 
> is an abbreviation of
> 
> for x in xs:
>   if cond(x)
>     yield e(x)
> 
> and similarly with more for and if clauses,
> whereas the analogous expansion of your proposal
> 
> for x in xs:
>   while cond(x):
>      yield e(x)
> 
> is an infinite loop and not at all what you mean.

That's because while is being used here with a different semantic to the while loop. It actually means:

for x in xs:
    if not cond(x):
        break
    yield e(x)

and for 'from':


emit = False
for x in xs:
    if not emit:
        if cond(x):
            emit = True
    else:
        yield e(x)


Cheers,

Nick

[toc] | [next] | [standalone]


#54831

FromNick Mellor <thebalancepro@gmail.com>
Date2013-09-26 07:50 -0700
Message-ID<dd8ad365-2509-4727-9097-7d7c36d95d23@googlegroups.com>
In reply to#54829
On Friday, 27 September 2013 00:39:30 UTC+10, Nick Mellor  wrote:

[snip]
> for x in xs:
>     if not emit:
>         if cond(x):
>             emit = True
>     else:
>         yield e(x)
> 

Oops!

for x in xs:
   if not emit:
       if cond(x):
           emit = True
           yield e(x)
   else:
       yield e(x)

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web