Iterators

Iterator Protocol

  1. # get iterator
  2. numbers = [1, 2, 3]
  3. iterator = iter(numbers)
  4. #ans: call next
  5. next(iterator)
  6. #ans: 1
  7. next(iterator)
  8. #ans: 2
  9. next(iterator)
  10. #ans: 3
  11. #ans: next(iterator) # StopIteration

For Loop Uses Iterators

  1. # for loop = iterator protocol
  2. for num in [1, 2, 3]:
  3. print(num)
  4. #ans: equivalent to:
  5. iterator = iter([1, 2, 3])
  6. while True:
  7. try:
  8. num = next(iterator)
  9. print(num)
  10. except StopIteration:
  11. break

Custom Iterator

  1. # iterator class
  2. class Counter:
  3. def __init__(self, start, end):
  4. self.current = start
  5. self.end = end
  6. def __iter__(self):
  7. return self
  8. def __next__(self):
  9. if self.current >= self.end:
  10. raise StopIteration
  11. self.current += 1
  12. return self.current - 1
  13. for num in Counter(0, 3):
  14. print(num)
  15. #ans: 0, 1, 2

Iterable vs Iterator

  1. # iterable: has __iter__()
  2. #ans: iterator: has __iter__() and __next__()
  3. #ans: list is iterable but not iterator
  4. numbers = [1, 2, 3]
  5. iter(numbers)
  6. #ans: works
  7. #ans: next(numbers) # TypeError
  8. #ans: iterator is both
  9. iterator = iter(numbers)
  10. iter(iterator)
  11. #ans: returns itself
  12. next(iterator)
  13. #ans: 1

Exercises - Part 1

  1. # what is iter()?
  2. lst = [1, 2, 3]
  3. it = iter(lst)
  4. type(it)
  5. #ans: list_iterator

Exercises - Part 2

  1. # next() on list?
  2. lst = [1, 2, 3]
  3. next(lst)
  4. #ans: TypeError (list not iterator)

Exercises - Part 3

  1. # StopIteration when?
  2. it = iter([1, 2])
  3. next(it)
  4. #ans: 1
  5. next(it)
  6. #ans: 2
  7. next(it)
  8. #ans: StopIteration

Exercises - Part 4

  1. # iterator exhaustion?
  2. it = iter([1, 2])
  3. list(it)
  4. #ans: [1, 2]
  5. list(it)
  6. #ans: [] (exhausted)

Exercises - Part 5

  1. # iter on iterator?
  2. it = iter([1, 2, 3])
  3. iter(it) is it
  4. #ans: True (returns self)

Exercises - Part 6

  1. # range is iterator?
  2. r = range(3)
  3. next(r)
  4. #ans: TypeError (range is iterable not iterator)
  5. iter(r)
  6. #ans: works (creates iterator)

Exercises - Part 7

  1. # string is iterable?
  2. s = "abc"
  3. for c in s:
  4. print(c)
  5. #ans: a, b, c

Exercises - Part 8

  1. # dict iterator?
  2. d = {"a": 1, "b": 2}
  3. it = iter(d)
  4. next(it)
  5. #ans: "a" (iterates keys)

Exercises - Part 9

  1. # custom __iter__ only?
  2. class MyIterable:
  3. def __iter__(self):
  4. return iter([1, 2, 3])
  5. for x in MyIterable():
  6. print(x)
  7. #ans: 1, 2, 3

Exercises - Part 10

  1. # infinite iterator?
  2. class InfiniteCounter:
  3. def __init__(self):
  4. self.count = 0
  5. def __iter__(self):
  6. return self
  7. def __next__(self):
  8. self.count += 1
  9. return self.count
  10. #ans: never raises StopIteration

Google tag (gtag.js)