Space Ostrich
Space Ostrich

Reputation: 423

How can I print a value returned by a generator function?

I'm trying to print the third value returned by a generator function that generates odd numbers less than 10. However, I haven't been able to print any values at all. The most common answer to this question I've found has been the code below.

def get_odds():
    yield (n for n in range(10) if n % 2 != 0)
for n in get_odds():
    print(n)

This returns:

<generator object get_odds.<locals>.<genexpr> at 0x000001C88ABFC258>

It should return 1, then 3, and so on. How do I return the value generated by a generator function?

Upvotes: 0

Views: 633

Answers (2)

Mad Physicist
Mad Physicist

Reputation: 114578

The expression (n for n in range(10) if n % 2 != 0) is a generator in its own right. It is what your print statement is picking up when you yield it. Here are a few ways to rewrite your code to behave as you want it to.

The trivial:

for n in (n for n in range(10) if n % 2 != 0): 
    print(n)

A generator function without an explicit yield:

def get_odds():
    return (n for n in range(10) if n % 2 != 0)
for n in get_odds():
    print(n)

A generator function with a yield:

def get_odds():
    for n in range(10): 
        if n % 2:
            yield n
for n in get_odds():
    print(n)

An overkilled fix for the code as posted:

def get_odds():
    yield (n for n in range(10) if n % 2 != 0)
for n in next(get_odds()):
    print(n)

Upvotes: 3

Pythonify
Pythonify

Reputation: 11

in your way, your generator contain another generator

>>> def get_odds():
...     yield (n for n in range(10) if n % 2 != 0)


>>> odd = get_odds()
>>> odd
<generator object get_odds at 0x102270f10>
>>> n = next(odd)
>>> n
<generator object get_odds.<locals>.<genexpr> at 0x102270eb8>
>>> next(n)
1
>>> next(n)
3
>>> next(n)
5

you should write code like this:

def get_odds():
    for n in range(10):
        if n % 2 != 0:
            yield n

Upvotes: 1

Related Questions