Python · Advanced 2
Iterators and Generators
Name
Class
Date
Mark / 29
Section A
Circle the letter of the correct answer. One mark each.
- 1What happens when a generator function is called?1
- AIt runs to the first yield and prints a value
- BIt raises StopIteration
- CIt runs the whole body and returns a list
- DIt returns a generator object and does not yet run the body
- 2What does the
yieldstatement do?1- ARestarts the function
- BReturns a value and pauses the function, keeping its state
- CEnds the function for good
- DPrints a value to the screen
- 3What does a for loop do when the iterator raises StopIteration?1
- ASkips the next item
- BStarts again from the beginning
- CEnds normally
- DCrashes with an error
- 4What is the main advantage of a generator over a list for a very long sequence?1
- AIt can be indexed quickly
- BIt holds one value at a time, so uses very little memory
- CIt can be used again and again
- DIt can be sorted without a function
- 5A generator is used in a for loop which is finished. A second for loop is then run over the same generator. What happens?1
- AAn error is raised
- BThe loop runs twice as fast
- CThe generator restarts
- DThe second loop does nothing, because the generator is used up
- 6Which of these is a generator expression?1
- A[n * n for n in range(5)]
- B(n * n for n in range(5))
- Cn * n in range(5)
- D{n * n for n in range(5)}
- 7What does
yield from other()do?1- APasses on every value that other() produces
- BStops the generator
- CReturns the first value of other()
- DCalls other() and discards the result
- 8What does
any(check(n) for n in items)do once check returns True?1- AChecks every item anyway
- BRaises StopIteration
- CStops, without checking the remaining items
- DStarts again from the first item
- 9In a pipeline of generators, in what order are items processed?1
- AThe stages run at the same time on different items
- BEvery item goes through the first stage, then the second
- CEach item goes through every stage before the next is read
- DIn the reverse order
- 10What does
itertools.islice(fibonacci(), 10)give you?1- AThe first ten items of an infinite generator
- BThe tenth item only
- CAn error, since the generator is infinite
- DA list of ten random numbers
Section B
Answer in the space provided. The number of marks tells you how many separate points to make.
- 1ExplainExplain what is meant by a generator in Python, and give one advantage of using a generator instead of building a list.3
- 2StateThe program shown is run. State the output, in the order it is displayed.4Python
def mystery(n): for i in range(n): print("making", i) yield i * 2 g = mystery(3) print("start") print(next(g)) print(next(g)) - 3WriteWrite a generator function called evens that takes a number, limit, and yields each of the even numbers from 0 up to but not including limit.3
- 4ExplainExplain the difference between an iterable and an iterator in Python.3
- 5DiscussA program has to find the first line containing the word ERROR in a log file that is many gigabytes in size. Discuss whether the program should read the whole file into a list or process it using a generator.6
Mark scheme
Section A
Section B
1 Explain what is meant by a generator in Python, and give one advantage of using a generator instead of building a list. 3
One mark for each of the following, to a maximum of 3.
- A generator is a function that uses yield to produce a sequence of values one at a time
- It pauses after each value and carries on from the same place when the next is requested
- Advantage: the values are made only when needed, so it uses far less memory than a list holding them all
Model answer. A generator is a function that uses yield to produce a sequence of values one at a time. After each value it pauses, keeping its local variables, and carries on from the same place when the next value is requested. An advantage is that the values are only made when they are needed, so a generator uses far less memory than a list that holds every value at once, and can even produce an infinite sequence.
2 The program shown is run. State the output, in the order it is displayed. 4
One mark for each of the following, to a maximum of 4.
- start is output first, because calling the generator function does not run its body
- making 0 is output when the first next is called
- then 0 is output by the print statement
- making 1 and then 2 are output for the second next. The output is start, making 0, 0, making 1, 2
Model answer. The output is: start, making 0, 0, making 1, 2 (each on a separate line). Calling mystery(3) only creates the generator, so start is printed first. The first call of next runs the body until the first yield, which prints making 0 and returns 0, and that value is printed. The second call of next carries on from the yield, prints making 1 and returns 2, which is printed. The third item is never asked for, so making 2 is never printed.
3 Write a generator function called evens that takes a number, limit, and yields each of the even numbers from 0 up to but not including limit. 3
One mark for each of the following, to a maximum of 3.
- A function definition with a parameter and a loop
- Selects the even numbers (steps of 2 or a modulus test)
- Uses yield to produce each value
Model answer.
def evens(limit):
for n in range(0, limit, 2):
yield n
print(list(evens(9)))The function loops through the numbers from 0 in steps of 2 and uses yield to produce each one, so it is a generator. list(evens(9)) gives [0, 2, 4, 6, 8].
4 Explain the difference between an iterable and an iterator in Python. 3
One mark for each of the following, to a maximum of 3.
- An iterable is an object that can be looped over, such as a list or string
- An iterator is the object that produces the items one at a time, using next()
- An iterator is used up: it keeps its position and raises StopIteration at the end, but an iterable can be looped over again and again
Model answer. An iterable is an object that can be looped over, such as a list or a string, and it can give a new iterator whenever one is needed. An iterator is the object that produces the items one at a time each time next() is called, and it remembers its position. When it has no more items it raises StopIteration, and it is then used up, whereas an iterable such as a list can be looped over again and again.
5 A program has to find the first line containing the word ERROR in a log file that is many gigabytes in size. Discuss whether the program should read the whole file into a list or process it using a generator. 6
One mark for each of the following, to a maximum of 6.
- Reading the whole file into a list would need enough memory to hold every line
- The file might be larger than the available memory, so the program could crash or become very slow
- A generator reads and processes one line at a time, so memory use stays small whatever the size of the file
- The generator stops as soon as the first matching line is found, so the rest of the file is never read
- A list would allow the lines to be used again or looked up by index, which is not needed for this task
- A reasoned conclusion: use a generator (or iterate over the file line by line)
Model answer. A program that reads the whole file into a list would need enough memory to hold every line at once. If the file is several gigabytes this might be more than the computer has, so the program could crash or become very slow. A generator reads and handles one line at a time, so the memory used stays small whatever the size of the file. It also stops as soon as the first line containing ERROR is found, so the rest of the file is never read, saving time. A list would have the advantage that the lines could be used again or looked up by position, but this task does not need that. The program should therefore process the file with a generator, for example by looping over the file line by line.