[Python-ideas] Generator syntax hooks?

Terry Reedy tjreedy at udel.edu
Wed Aug 9 17:22:40 EDT 2017


On 8/9/2017 10:54 AM, Nick Coghlan wrote:
> On 9 August 2017 at 15:38, Guido van Rossum <guido at python.org> wrote:
>> On Tue, Aug 8, 2017 at 10:06 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
>>> The OP's proposal doesn't fit into that category though: rather it's
>>> asking about the case where we have an infinite iterator (e.g.
>>> itertools.count(0)), and want to drop items until they start meeting
>>> some condition (i.e. itertools.dropwhile) and then terminate the
>>> iterator as soon as another condition is no longer met (i.e.
>>> itertools.takewhile).
>>
>> I don't think that's what the OP meant. The original proposal seemed to
>> assume that it would be somehow reasonable for the input ("integers" in the
>> example) to be able to see and parse the condition in the generator
>> expression ("1000 <= x < 100000" in the example, with "x" somehow known to
>> be bound to the iteration value). That's at least what I think the remark "I
>> like mathy syntax" referred to.
> 
> Right, I was separating the original request to make "{x for x in
> integers if 1000 <= x < 1000000}" work into the concrete proposal to
> make exactly *that* syntax work (which I don't think is feasible), and
> the slightly more general notion of offering a more math-like syntax
> that allows finite sets to be built from infinite iterators by
> defining a termination condition in addition to a filter condition.

We already have three nice one liners for that, one of which you gave.

x = set(filter(filter_condition, takewhile(continue_condition, source)))
x = set(x for x in takewhile(continue_condition, source) if 
filter_condition)
x = {x for x in takewhile(continue_condition, source) if filter_condition}

Replace takewhile with islice(source, max) if the continue condition is 
(number seen < max).  Add enumerate if the running count is needed 
otherwise.

Terminating an infinite iterator and filtering the initial slice are 
different operations.  The operations are easily composed as they are, 
in multiple ways.  Trying to mix them together in one jumbled special 
syntax is a bad idea to me.

>>> There aren't any technical barriers I'm aware of to implementing that,
>>> with the main historical objection being that instead of the
>>> comprehension level while clause mapping to a while loop directly the
>>> way the for and if clauses map to their statement level counterparts,
>>> it would instead map to the conditional break in the expanded
>>> loop-and-a-half form:
>>>
>>>      while True:
              <do something>
>>>          if not condition:
>>>              break

In other words, aside from other issues, you would have 'while' mean 
'do...while' in this one special place.  -1.

-- 
Terry Jan Reedy



More information about the Python-ideas mailing list