# itertools

Some quick reference notes made on the itertools library

import itertools ### chain ### Takes any number of iterables, back-to-backs them so you can iterate through all if the iterators in a single loop >>> [ i for i in itertools.chain( [1, 2, 3], [4, 5, 6], [7, 8, 9] ) ] [1, 2, 3, 4, 5, 6, 7, 8, 9] ### combinations ### Think of nCr and nPr. In the example below, it returns unique pairs (hence the second arg, 2) for the set of values in the first arg - the list >>> [ i for i in itertools.combinations( [1, 2, 3, 4], 2) ] [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] ### cycle ### For the iterable passed as an argument, cycle through each element, wrapping back to the start at the end it = itertools.cycle([1, 2, 3]) it.next() -> 1, 2, 3, 1, ... ### dropwhile ### Iterate through a sequence until the lambda test (predicate) is True. Return all of the seq as soon as the test is satisfied >>> [ i for i in itertools.dropwhile( lambda x: x < 3, [1, 2, 3, 4, 5, 1] ) ] [3, 4, 5, 1] ### groupby ### Bundles the elements of the first arg into iterators for each unique element (can also define a grouping fn) >>> [ i for i in itertools.groupby([1, 2, 3, 2]) ] [(1, <itertools._grouper>), (2, <itertools._grouper>), (3, <itertools._grouper>)] # 2's grouper has more data ### ifilter ### Just like filter. You pass either a lambda or None as the predicate >>> [ i for i in itertools.ifilter(None, [1, 0, 7, 8]) ] [1, 7, 8] ### ifilterfalse ### Opposite of ifilter. Would return [0] for the example of ifilter ### imap ### Same as map except you can also use it to zip elements together, pushing them in to the same lambda: >>> [ i for i in itertools.imap(lambda x, y: '%s%s' % (x, y), [1, 2, 3], [4, 5, 1]) ] ['14', '25', '31'] ### islice ### Like slicing for lists, this iterates over a sequence, returning every 2nd elem from 1st index until 1000th elem >>> [ i for i in itertools.islice(['MSFT', 26, 'AAPL', 660, 'FBOOK', 0.01], 1, 1000, 2) ] [26, 660, 0.01] ### izip ### Just like zip, returns nth elem of multiple sequences together >>> [ i for i in itertools.izip( ['a', 'b', 'c'], ['m', 'n'] ) ] [('a', 'm'), ('b', 'n')] # notice 'c' is missing ### izip_longest ### Just like izip but fills in blanks with Nones >>> [ i for i in itertools.izip_longest( ['a', 'b', 'c'], ['m', 'n'] ) ] [('a', 'm'), ('b', 'n'), ('c', None)] ### permutations ### See combinations - nPr rather than nCr >>> [ i for i in itertools.permutations( [1, 2, 3, 4], 2) ] [(1, 2), (1, 3), (1, 4), (2, 1), (2, 3), (2, 4), (3, 1), (3, 2), (3, 4), (4, 1), (4, 2), (4, 3)] ### product ### Cartesian product of all elements from each of the sequences passed as args - join everything from table A to table B and repeat over for table C ... >>> [ i for i in itertools.product(['a', 'b'], ['c', 'd']) ] [('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd')] ### repeat ### Repeats to first arg 4 times in example below. Will repeat endlessly without the 2nd arg >>> [ i for i in itertools.repeat(10, 4) ] [10, 10, 10, 10] ### starmap ### Like a map inside a map function. (I think this fn is of less use) >>> [ i for i in itertools.starmap( pow, [ [2, 3], [7, 3] ] ) ] [8, 343] ### takewhile ### Opposite of dropwhile - failing as soon as the predicate returns True >>> [ i for i in itertools.takewhile( lambda x: x < 3, [1, 2, 3, 4, 5, 1] ) ] [1, 2] ### tee ### For a given sequence (1, 2), returns 3 copies of the same sequence to iterate over >>> i, j, k = itertools.tee([1, 2], 3) >>> i.next() 1 >>> i.next() 2 >>> i.next() StopIteration >>> j.next() 1 >>> j.next()