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
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
- An analysis of the leftpad incident
- Dependency Hell
- An attempt fix to dependency hell
COMP1531 21T1 - 10.1 - Python - Iterators & Generators
By haydensmith
COMP1531 21T1 - 10.1 - Python - Iterators & Generators
- 589