5.31. Iterators#

An iterator is a special type of object that can be iterated (looped) over. You will encounter cases where a function you would expect to return a series that could be sliced instead returns a generator object that has to be iterated over in order to obtain it’s contents.

For example, the built in function reversed().

new_order = reversed(["e", "a", "b", "g"])
new_order
<list_reverseiterator at 0x7ff918c7eeb0>

Looping works

for element in new_order:
    print(element)
g
b
a
e

If you just want such an object to be a list, for example, then a more succinct approach is to cast it using list().

new_order = reversed(["e", "a", "b", "g"])
new_order = list(new_order)
new_order
['g', 'b', 'a', 'e']

5.31.1. The yield keyword#

You can write your own generator functions by using the keyword yield instead of return.

There are several benefits of generator functions. Just one of which is they provide a means for iterating over some data series without having to load everything into memory. For instance, if you have a massive data file of human genetic variants and but you only want 100 records where the alleles are C/T and on chromosome 10.

5.31.2. The as keyword#

This keyword facilitates a type of assignment. They can be used in a number of different contexts, such as part of a with statement.

with open("some_path.txt") as infile:
    lines = infile.readlines()

They can also be used in imports and when trapping exceptions.

5.32. Exercises#

  1. data is a list of the characters from words put onto separate lines. The space between words being indicated by a blank line. Write an algorithm that reconstructs the original words and spaces as a single string.

    data = """s
    o
    m
    e
    
    t
    e
    x
    t""".splitlines()
    
    'some text'
    
  2. Write a function that takes a file path, opens the file and returns all the lines in that file.

  3. Convert the above function to a generator that yields one line at a time.