# [Python-ideas] [Python-Dev] yield * (Re: Missing operator.call)

Steven D'Aprano steve at pearwood.info
Sun Feb 8 09:14:46 CET 2009

```Leif Walsh wrote:

> I still don't understand why such a construct is necessary.  Is
>
>>>> for elt in iterable:
>>>>     yield elt
>
> really all that bad?  Maybe it's a little silly-looking, but at least
> it's easy to understand and not _that_ hard to type....

It's not just silly looking, it's the same construct used repeatedly, in
many different places in code. It is a basic principle of programming
that anytime you have blocks of code that are almost identical, you
should factor out the common code into it's own routine. See "Don't
Repeat Yourself" and "Once And Only Once" for similar ideas:

http://c2.com/cgi/wiki?OnceAndOnlyOnce
http://c2.com/cgi/wiki?DontRepeatYourself

Consider a pure Python implementation of itertools.chain:

def chain(*iterables):
for it in iterables:
for elt in it:
yield elt

The double for loop obscures the essential nature of chain. From
help(itertools.chain):

"Return a chain object whose .next() method returns elements from the
first iterable until it is exhausted, then elements from the next
iterable, until all of the iterables are exhausted."

The emphasis is on iterating over the sequence of iterables, not
iterating over each iterable itself. This is one place where explicit is
*not* better than implicit, as the inner loop exposes too much of the
as this:

def chain(*iterables):
for it in iterables:
yield from it

Naturally you can use map and filter to transform the results:

yield from map(trans, filter(expr, it))

The advantage is even more obvious when married with a generator expression:

yield from (3*x for x in seq if x%2 == 1)

for x in seq:
if x%2 == 1:
yield 3*x

or

for y in (3*x for x in seq if x%2 == 1):
yield y

I'm +1 on this suggestion, especially since it requires no new keywords.

--
Steven

```