[Python-Dev] accumulator display syntax

Phillip J. Eby pje at telecommunity.com
Fri Oct 17 16:15:04 EDT 2003

At 12:46 PM 10/17/03 -0700, Brett C. wrote:
>Skip Montanaro wrote:
>>Is it supposed to return a generator function which I
>>can assign to a variable (or pass to the builtin function sum() as in your
>>example) and call later, or is it supposed to turn the current function into
>>a generator function (so that each executed yield statement returns a value
>>to the caller of the current function)?
>It returns a generator function.

No, it returns an iterator.  Technically a generator-iterator, but 
definitely not a generator function, just as [x for x in y] doesn't return 
a function that returns a list.  :)

>Personally I am not seeing any extreme need for this feature.  I mean the 
>example I keep seeing is ``sum((yield x*2 for x in foo))``.  But how is 
>this such a huge win over ``sum([x*2 for x in foo])``?  I know there is a 
>memory perk since the entire list won't be constructed, but unless there 
>is a better reason I see abuse on the horizon.

It's not an extreme need; if it were, it'd have been added in 2.2, where 
all extreme Python needs were met.  ;)

>I know I am personally +0 on this even after my above worries since I 
>don't see my above arguments are back-breakers and those of us who do know 
>how to properly to use it will get a perk out of it.

I'm sort of +0 myself; there are probably few occasions where I'd use a 
gencomp.  But I'm -1 on creating special indexing or listcomp-like 
accumulator syntax, so gencomps are a fallback position.

I'm not sure gencomp is the right term for these things anyway...  calling 
them iterator expressions probably makes more sense.  Then there's not the 
confusion with generator functions, which get called.  And this discussion 
has made it clearer that having 'yield' in the syntax is just plain wrong, 
because yield is a control flow statement.  These things are really just 
expressions that act over iterators to return another iterator.  In 
essence, an iterator expression is just syntax for imap and ifilter, in the 
same way that a listcomp is syntax for map and filter.

Really, you could now write imap and ifilter as functions that compute 
iterator expressions, e.g.:

imap = lambda func,items: func(item) for item in items

ifilter = lambda func, items: item for item in items if func(item)

Which of course means there'd be little need for imap and ifilter, just as 
there's now little need for map and filter.

Anyway, if you look at '.. for .. in .. [if ..]' as a ternary or quaternary 
operator on an iterator (or iterable) that returns an iterator, it makes a 
lot more sense than thinking of it as having anything to do with 
generator(s).  (Even if it might be implemented that way.)

More information about the Python-Dev mailing list