34

Is there a one-line expression for:

for thing in generator:
    yield thing

I tried yield generator to no avail.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
Walrus the Cat
  • 2,314
  • 5
  • 35
  • 64

3 Answers3

43

In Python 3.3+, you can use yield from. For example,

>>> def get_squares():
...     yield from (num ** 2 for num in range(10))
... 
>>> list(get_squares())
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

It can actually be used with any iterable. For example,

>>> def get_numbers():
...     yield from range(10)
... 
>>> list(get_numbers())
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> def get_squares():
...     yield from [num ** 2 for num in range(10)]
... 
>>> list(get_squares())
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Unfortunately, Python 2.7 has no equivalent construct :'(

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • I don't think the helper function does exactly the same in Py2.7 as what `yield from` does in Py3.3. Calling this function just returns another generator object, so it is pretty similar to the built-in `iter`. If you call your `yield_from()` from within a function, this function will not automatically become a generator function, as will happen with `yield from`. As far as I [understand](https://www.python.org/dev/peps/pep-0380/#motivation), in Py2.7, you need to write the explicit for-loop as shown by the OP. – Bas Swinckels Apr 04 '15 at 11:47
  • @BasSwinckels Yup, the helper function is not the same. But, you can delegate the generator to that function and it would make the code simpler, no? – thefourtheye Apr 04 '15 at 11:49
  • No, I think the helper function is useless, since it does not yield from the calling function. As shown in the PEP, this `for i in generator: yield i` can not be factored out into a separate function. You just rewrote `iter` ... :) – Bas Swinckels Apr 04 '15 at 11:51
11

You can use a list comprehension to get all of the elements out of a generator (assuming the generator ends):

[x for x in generator]
Ramón J Romero y Vigil
  • 17,373
  • 7
  • 77
  • 125
  • would this negate some of the lazy properties of generators, i.e. convert its output to a list? – Walrus the Cat Apr 04 '15 at 12:12
  • Absolutely. By converting to a list you are allocating all of the memory necessary to warehouse the data "generated" by the generator. Also, if the generator does not complete the above statement will never terminate. – Ramón J Romero y Vigil Apr 04 '15 at 12:14
  • 4
    No, that's the heavy cost of converting a generator into a memory representation. I would suggest considering *why* you're converting from a generator to a list; in most instances you don't want to force the generator to evaluate until necessary. – Ramón J Romero y Vigil Apr 04 '15 at 12:50
0

Here is a simple one-liner valid in Python 2.5+ as requested ;-):

for thing in generator: yield thing
davidedb
  • 867
  • 5
  • 12