listbut runtime behavior is nicer obviouslythis generator comprehension also has imperative versionsfor exampledef get_log_lines(log_file)line read_line(log_filewhile truetryif complex_condition(line)yield line line read_line(log_fileexcept stopiterationraise log_lines get_log_lines(huge_log_fileyesthe imperative version could be simplified toobut the version shown is meant to illustrate the behind-the-scenes "howof for loop over an iteratable--more details we also want to abstract from in our thinking in facteven using yield is somewhat of an abstraction from the underlying "iterator protocol we could do this with class that had __next__(and __iter__(methods for exampleclass getloglines(object)def __init__(selflog_file)self log_file log_file self line none def __iter__(self)return self def __next__(self)if self line is noneself line read_line(log_filewhile not complex_condition(self line)self line read_line(self log_filereturn self line log_lines getloglines(huge_log_fileaside from the digression into the iterator protocol and laziness more generallythe reader should see that the comprehension focuses attention much better on the "what,whereas the imperative version--although successful as refactorings perhaps--retains the focus on the "how dicts and sets in the same fashion that lists can be created in comprehensions rather than by creating an empty listloopingand repeatedly call (avoidingflow control