4

How do we yield from another sub-generator, but with transformation/processing?

for example: in code below, main_gen yields x after transformation using f(x)

def f(x):
   return 2*x

def main_gen():
   for x in sub_gen():
      yield f(x)

can this be replaced with yield from and if so how?

def main_gen():
     yield from ***
toing
  • 466
  • 1
  • 3
  • 19

2 Answers2

6

You could do:

def main_gen():
    yield from map(f, sub_gen())
   

But then, why not:

def main_gen():
    return map(f, sub_gen())

Which is a lazy iterator anyway.

user2390182
  • 72,016
  • 6
  • 67
  • 89
  • 1
    Importantly, the main benefit of `yield from` (allowing `send` to delegate to the subgenerator instead of being received by the wrapping generator; the reason it was created in the first place, rather than just telling programmers to explicitly `yield` each item like the OP was doing in the first place) is lost when you wrap in `map`, so there is little benefit to using `yield from` over just returning the `map` unless you have some other values to `yield` before or after (where a single return wouldn't work without wrapping, e.g. via `itertools.chain`, making `yield` the less complex option). – ShadowRanger Oct 29 '20 at 20:22
  • You could write a function `map_gen` and reuse it. – Peter Wood Oct 29 '20 at 20:27
3

You can always just transform this to a generator expression and yield from that:

def main_gen():
    yield from (f(x) for x in sub_gen())
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
  • 2
    What do you gain from that? The original `for` loop could be written `for x in sub_gen(): yield f(x)` if you want to one-line it, all this does is add a layer of unnecessary wrapping. – ShadowRanger Oct 29 '20 at 20:24
  • 1
    To be honest the original code seems perfectly fine to me. The OP wanted to use `yield from` so... – Tomerikoo Oct 29 '20 at 20:26