def iterator_demos(): """Using iterators >>> s = [[1, 2], 3, 4, 5] >>> next(s) Traceback (most recent call last): ... TypeError: 'list' object is not an iterator >>> t = iter(s) >>> next(t) [1, 2] >>> next(t) 3 >>> u = iter(s) >>> next(u) [1, 2] >>> list(t) [4, 5] >>> next(t) Traceback (most recent call last): ... StopIteration >>> d = {'one': 1, 'two': 2, 'three': 3} # Keys and values >>> k = iter(d) # next(k) >>> v = iter(d.values()) # next(v) >>> k = iter(d) >>> d.pop('two') 2 >>> next(k) Traceback (most recent call last): ... RuntimeError: dictionary changed size during iteration """ def contains(a, b): """Return whether sequence A contains all the elements of B in order. >>> contains('strength', 'stent') True >>> contains('strength', 'rest') False >>> contains('strength', 'tenth') True """ ai = iter(a) for x in b: try: while next(ai) != x: pass except StopIteration: return False return True def double(x): print('***', x, '=>', 2*x, '***') return 2*x def built_in_demo(): """Using built-in sequence functions. >>> bcd = ['b', 'c', 'd'] >>> [x.upper() for x in bcd] ['B', 'C', 'D'] >>> caps = map(lambda x: x.upper(), bcd) >>> next(caps) 'B' >>> next(caps) 'C' >>> s = range(3, 7) >>> doubled = map(double, s) >>> next(doubled) *** 3 => 6 *** 6 >>> next(doubled) *** 4 => 8 *** 8 >>> list(doubled) *** 5 => 10 *** *** 6 => 12 *** [10, 12] >>> f = lambda x: x < 10 >>> a = filter(f, map(double, reversed(s))) >>> list(a) *** 6 => 12 *** *** 5 => 10 *** *** 4 => 8 *** *** 3 => 6 *** [8, 6] >>> t = [1, 2, 3, 2, 1] >>> reversed(t) == t False >>> list(reversed(t)) == t True >>> d = {'a': 1, 'b': 2, 'c': 3} >>> items = zip(d.keys(), d.values()) # Call next(items) """ def plus_minus(x): """Yield x and -x. >>> t = plus_minus(3) >>> next(t) 3 >>> next(t) -3 >>> list(plus_minus(5)) [5, -5] >>> list(map(abs, plus_minus(7))) [7, 7] """ yield x yield -x def evens(start, end): """A generator function that returns even numbers. >>> list(evens(2, 10)) [2, 4, 6, 8] >>> list(evens(1, 10)) [2, 4, 6, 8] """ even = start + (start % 2) while even < end: yield even even += 2 class Countdown: """Count down to zero. >>> list(Countdown(5)) [5, 4, 3, 2, 1] >>> for x in Countdown(3): ... print(x) 3 2 1 """ def __init__(self, start): self.start = start def __iter__(self): v = self.start while v > 0: yield v v -= 1 def a_then_b_for(a, b): """The elements of a followed by those of b. >>> list(a_then_b_for([3, 4], [5, 6])) [3, 4, 5, 6] """ for x in a: yield x for x in b: yield x def a_then_b(a, b): """The elements of a followed by those of b. >>> list(a_then_b([3, 4], [5, 6])) [3, 4, 5, 6] """ yield from a yield from b def countdown(k): """Count down to zero. >>> list(countdown(5)) [5, 4, 3, 2, 1] """ if k > 0: yield k yield from countdown(k-1) def prefixes(s): """Yield all prefixes of s. >>> list(prefixes('both')) ['b', 'bo', 'bot', 'both'] """ if s: yield from prefixes(s[:-1]) yield s def substrings(s): """Yield all substrings of s. >>> list(substrings('tops')) ['t', 'to', 'top', 'tops', 'o', 'op', 'ops', 'p', 'ps', 's'] """ if s: yield from prefixes(s) yield from substrings(s[1:])