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


Groups > comp.lang.python > #54829

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

X-Received by 10.224.126.137 with SMTP id c9mr4211168qas.2.1380206370952; Thu, 26 Sep 2013 07:39:30 -0700 (PDT)
X-Received by 10.182.28.100 with SMTP id a4mr27092obh.28.1380206370914; Thu, 26 Sep 2013 07:39:30 -0700 (PDT)
Path csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!usenet.blueworldhosting.com!feeder01.blueworldhosting.com!border4.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!d5no1937895qap.0!news-out.google.com!9ni338qaf.0!nntp.google.com!d5no2027885qap.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail
Newsgroups comp.lang.python
Date Thu, 26 Sep 2013 07:39:30 -0700 (PDT)
In-Reply-To <1155070666.951023.161280@b28g2000cwb.googlegroups.com>
Complaints-To groups-abuse@google.com
Injection-Info glegroupsg2000goo.googlegroups.com; posting-host=124.168.80.34; posting-account=ZAg6xAoAAAAmY8bBi3VzYjWntm8Ct1P8
NNTP-Posting-Host 124.168.80.34
References <1154879331.903490.106020@m73g2000cwd.googlegroups.com> <1155064682.499991.246170@h48g2000cwc.googlegroups.com> <mailman.9113.1155069226.27775.python-list@python.org> <1155070666.951023.161280@b28g2000cwb.googlegroups.com>
User-Agent G2/1.0
MIME-Version 1.0
Message-ID <99048467-e7eb-461a-aa9b-e30cf5f6f1c7@googlegroups.com> (permalink)
Subject Re: Proposal: [... for ... while cond(x)]
From Nick Mellor <thebalancepro@gmail.com>
Injection-Date Thu, 26 Sep 2013 14:39:30 +0000
Content-Type text/plain; charset=ISO-8859-1
Lines 93
Xref csiph.com comp.lang.python:54829

Show key headers only | View raw


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

Back to comp.lang.python | Previous | NextNext in thread | Find similar | Unroll thread


Thread

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

csiph-web