Reputation: 3430
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.
<genexpr>
means when printing generator2()
?Upvotes: 1
Views: 202
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