for x in y(): how does this work?
I was looking for code to spin a cursor in the terminal and found this. I was wondering what was happening in the code. In particular
for c in spinning_cursor(): I've never seen this syntax. Is it because I am returning one element from a generator at a time with
yield, and this is assigned to c? Any other examples of this for x in y() use?
import sys import time def spinning_cursor(): cursor='/-\|' i = 0 while 1: yield cursor[i] i = (i + 1) % len(cursor) for c in spinning_cursor(): sys.stdout.write(c) sys.stdout.flush() time.sleep(0.1) sys.stdout.write('\b')
spinning_cursor() returns a generator, the code inside
spinning_cursor() doesn't actually run until you start iterating over the generator. Iterating over a generator means the code in the function is executed until it comes across a
yield statement, at which point the result of the expression there is returned as the next value and execution is paused again.
for loop does just that, it'll call the equivalent of
next() on the generator, until the generator signals it is done by raising
StopIteration (which happens when the function returns). Each return value of
next() is assigned, in turn, to
You can see this by creating the generator on in the Python prompt:
>>> def spinning_cursor(): ... cursor='/-\|' ... i = 0 ... while 1: ... yield cursor[i] ... i = (i + 1) % len(cursor) ... >>> sc = spinning_cursor() >>> sc <generator object spinning_cursor at 0x107a55eb0> >>> next(sc) '/' >>> next(sc) '-' >>> next(sc) '\\' >>> next(sc) '|'
This specific generator never returns, so
StopIteration is never raised and the
for loop will go on forever unless you kill the script.