COMP1531

10.1 - Python - Iterations & Generators

Iterators & Generators

  • Evan Kohilas gave a more extensive talk on this topic during a CSESoc supported event a couple of weeks ago - but we will cover them lightly today

https://www.youtube.com/watch?v=1oiUTdKuPxY&feature=youtu.be&fbclid=IwAR2gH4uv9yhPfXpSJJxcoapOtuSdQGFjULfoX37mr6TTCc9RHANQuTh-Lnk

 

 

Iterators

  • In Python, iterators are objects containing a countable number of elements
  • For example, we can get an iterator for a list:
animals = ["dog", "cat", "chicken", "sheep"]

animal_iterator = iter(animals)

Iterators

  • Any object with the methods __iter__() and __next__() is an iterator
  • Simple example (squares)
class Squares:
    def __init__(self):
        self.i = 0

    def __iter__(self):
        return self

    def __next__(self):
        self.i += 1
        return self.i*self.i

For loops

  • Python for loops use iterators behind the scenes
  • This is valid code:
squares = Squares()

for i in squares: # Loops forever
    print(i)

Iterator vs Iterable

  • Intuitively:
    • An iterator stores the state of the iteration (i.e. where it's up to).
    • Something is iterable if it can be iterated over.
  • Concretely:
    • An iterator has __iter__() and __next()__ methods.
    • Iterables have __iter__() methods
  • Thus, all iterators are iterable, but not all iterables are iterators
  • For example, lists are iterable, but they are not iterators
  • For loops only need to be given something iterable

Generators

  • A different way of writing iterators
  • Defined via generator functions instead of classes
  • Example generator
def simple_generator():
    print("Hello")
    yield 1
    print("Nice to meet you")
    yield 2
    print("I am a generator")

Generators

  • Intuitively, you can think of a generator as a suspendable computation
  • Calling next() on a generator executes it until it reaches a yield, at which point it is suspended (frozen) until the subsequent call to next()

Generators

  • More useful examples
def squares():
    i = 0
    while True:
        i += 1
        yield i*i
def fib():
    a = 1
    b = 1
    while True:
        yield a
        a, b = b, a+b

Libraries

  • Most code re-use is through libraries.
  • Software engineering can be an exercise in composing libraries to do what we want.
  • This is necessary for building useful software.
  • What's the downside?

Case study: leftpad

  • A Javascript library that had many users, mostly indirect
  • Owing to a disagreement, the author removed the library from NPM
  • This caused thousands of Javascript-based applications and libraries to break

The entire library

module.exports = leftpad;
function leftpad (str, len, ch) {
  str = String(str);
  var i = -1;
  if (!ch && ch !== 0) ch = ' ';
  len = len - str.length;
  while (++i < len) {
    str = ch + str;
  }
  return str;
}

Further reading

COMP1531 21T1 - 10.1 - Python - Iterators & Generators

By haydensmith

COMP1531 21T1 - 10.1 - Python - Iterators & Generators

  • 560