Saad
Saad

Reputation: 3430

Difference between different generators, "yield" and returning tuple iteration in a function

What is the proper difference between doing yield i from an iteration and return (i for i in range(10)).

def generator1():
    for i in range(10):
        yield i

def generator2():
    return (i for i in range(10))

For example, see these functions generator1() and generator2() both are differently written but both return a generator.

Outputs of IDLE:-

>>> generator1()
>>> <generator object generator1 at 0x107870468>

>>> generator2()
>>> <generator object generator2.<locals>.<genexpr> at 0x107870db0>

>>> import sys

>>> sys.getsizeof(generator1())
>>> 88
>>> sys.getsizeof(generator2())
>>> 88

As we can tell generator2() has fewer LOC (line of code) than generator2 and also the size of the object is the same, I've some questions.

Upvotes: 1

Views: 202

Answers (1)

Aaron Bentley
Aaron Bentley

Reputation: 1380

The difference is where the generator is defined. generator1 is a special generator function, because it contains a yield statement. generator functions always return generators. The generator is defined when you invoke generator1. generator2 is a regular function that uses a generator expression to construct a generator, and then returns it. The generator is defined when the line (i for i in range(10)) is executed. But if you add more logic, generator2 can return anything else, like None. For example:

def generator2(do_generator):
    if do_generator:
        return (i for i in range(10))
    else:
        return "I quit"

You can't do anything like that with generator1. It cannot return anything except a generator.

<genexpr> is short for generator expression. In your case, that's (i for i in range(10)). Generator expressions are very similar to list comprehensions, but they produce generators rather than lists.

Upvotes: 3

Related Questions