After reading answer1 and answer2, purpose of yield
still looks unclear.
In this first case, with the below function,
def createGenerator():
mylist = range(3)
for i in mylist:
yield i*i
On invoking createGenerator
, below,
myGenerator = createGenerator()
should return object(like (x*x for x in range(3))
) of type collections.abc.Generator
type, is-a collections.abc.Iterator
& collections.abc.Iterable
To iterate over myGenerator
object and get first value(0
),
next(myGenerator)
would actually make for
loop of createGenerator
function to internally invoke __iter__(myGenerator)
and retrieve collections.abc.Iterator
type object( obj
(say) ) and then invoke __next__(obj)
to get first value(0
) followed by the pause of for
loop using yield
keyword
If this understanding(above) is correct, then,
then, does the below syntax(second case),
def createGenerator():
return (x*x for x in range(3))
myGen = createGenerator() # returns collections.abc.Generator type object
next(myGen) # next() must internally invoke __next__(__iter__(myGen)) to provide first value(0) and no need to pause
wouldn't suffice to serve the same purpose(above) and looks more readable? Aren't both syntax memory efficient? If yes, then, when should I use yield
keyword? Is there a case, where yield
could be a must use?