yield_all needed in Python
Paul Moore
pf_moore at yahoo.co.uk
Thu Mar 3 15:47:42 EST 2005
Skip Montanaro <skip at pobox.com> writes:
> Doug> def foogen(arg1):
>
> Doug> def foogen1(arg2):
> Doug> # Some code here
>
> Doug> # Some code here
> Doug> yield_all foogen1(arg3)
> Doug> # Some code here
> Doug> yield_all foogen1(arg4)
> Doug> # Some code here
> Doug> yield_all foogen1(arg5)
> Doug> # Some code here
> Doug> yield_all foogen1(arg6)
>
> If this idea advances I'd rather see extra syntactic sugar introduced to
> complement the current yield statement instead of adding a new keyword.
You can work around the need for something like yield_all, or
explicit loops, by defining an "iflatten" generator, which yields
every element of its (iterable) argument, unless the element is a
generator, in which case we recurse into it:
>>> from types import GeneratorType
>>> def iflatten(it):
... it = iter(it)
... for val in it:
... if isinstance(val, GeneratorType):
... for v2 in iflatten(val):
... yield v2
... else:
... yield val
To take this one step further, you can define an @iflattened
decorator (yes, it needs a better name...)
>>> def iflattened(f):
... def wrapper(*args, **kw):
... for val in iflatten(f(*args, **kw)):
... yield val
... return wrapper
Now, we can do things like:
>>> @iflattened
... def t():
... def g1():
... yield 'a'
... yield 'b'
... yield 'c'
... def g2():
... yield 'd'
... yield 'e'
... yield 'f'
... yield g1()
... yield 1
... yield g2()
...
>>> list(t())
['a', 'b', 'c', 1, 'd', 'e', 'f']
This can probably be tidied up and improved, but it may be a
reasonable workaround for something like the original example.
Paul.
--
The most effective way to get information from usenet is not to ask
a question; it is to post incorrect information. -- Aahz's Law
More information about the Python-list
mailing list