[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