Learn generators by example. python As Iterators Using generators (generator functions) >>> def integers(): i = 1 while True: yield i i = i + 1>>> a = integers()>>> next(a)1>>> next(a)2>>> next(a)3>>> next(a)4>>> next(a)5>>> Assigning a to a varialble will automatically create .__next__() or next(generator) method generator This will allow you to iterate through the generator values Converting to list >>> def yrange(n): i = 0 while i < n: yield i i += 1>>> y = yrange(5)>>> list(y)[0, 1, 2, 3, 4]>>> list(y)[] You can convert a generator to a list however on the process it will lose its value and transfer it to the list. >> y = yrange(5)>>> ylist = list(y)>>> ylist[0, 1, 2, 3, 4]>>> ylist[0, 1, 2, 3, 4]>>> list(y)[] You may assign it to a variable to retain the list. Keep in mind it the original generator will be gone. The power to send to generators >>> def whizbang(): for i in range(10): x = yield i print('i got {}'.format(x))>>> bangbang = whizbang()>>> bangbang.__next__()0>>> next(bangbang)i got None1>>> bangbang.__next__()i got None2>>> next(bangbang)i got None3>>> bangbang.__next__()i got None4 next(generator) is the same as generator.__ (). Similar to how vars(class) is the same as class.__ . next__ dict__ >>> next(bangbang)i got None5 Let’s start sending stuff. Generators have generator.send() method. >>> bangbang.send('yo')i got yo6>>> bangbang.send('yo yo yo')i got yo yo yo7 In this case bangbang.send’s parameter is assigned to x. Since x = yield i, means x = yield send value and yield i >>> list(bangbang)i got Nonei got Nonei got None[8, 9] converting to list is not going to work with .send() >>> bangbang = whizbang()>>> next(bangbang)0>>> list(bangbang.send('test'))i got testException: TypeError: 'int' object is not iterable---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-1-5e0978d85904> in <module>()----> 1 list(bangbang.send('test')) TypeError: 'int' object is not iterable>>> you will need to call next(generator) at least once before doing a generator.send() >>> bangbang = whizbang()>>> bangbang.send('s')Exception: TypeError: can't send non-None value to a just-started generator---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-1-10a417413dc0> in <module>()----> 1 bangbang.send('s') TypeError: can't send non-None value to a just-started generator Removing values on generator early Cleaning the values inside a generator is useful. For example if your application run into unknownerror and that left your application on a dirty state instead of risk writing a wrong data you can just close the generator early. >>> bangbang = whizbang()>>> bangbang<generator object whizbang at 0x7f6b1537b288>>>> bangbang.__next__<method-wrapper '__next__' of generator object at 0x7f6b1537b288>>>> bangbang.__next__()0>>> bangbang.__next__()i got None1>>> bangbang.__next__()i got None2>>> bangbang.__next__()i got None3>>> bangbang.__next__()i got None4>>> bangbang.close()>>> bangbang.__next__()Exception: StopIteration: ---------------------------------------------------------------------------StopIteration Traceback (most recent call last)<ipython-input-1-6f12368577ae> in <module>()----> 1 bangbang.__next__() StopIteration: As you see above bangbang should iterate until 10 however it stopped at 4 since we called bangbang.close() Further reading http://anandology.com/python-practice-book/iterators.html https://jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/ https://stackoverflow.com/questions/10695456/what-is-the-result-of-a-yield-expression-in-python
Share Your Thoughts