#! /usr/bin/env python # -*- coding: utf-8 -*- """ Small Module to try every iterators. Online doc: https://docs.python.org/2/library/itertools.html And more at: https://docs.python.org/2/tutorial/datastructures.html#looping-techniques Credit: Lilian Besson for http://perso.crans.org/besson/cs101/solutions/examples/ License: GPLv3 """ # Import the 'itertools' module import itertools # Import the ANSIColors.printc function as printc: try: from ANSIColors import printc except ImportError: print "ImportError: No module named ANSIColors (defining printc as print)" def printc(*args, **kwargs): print(args, kwargs) if __name__ == '__main__': # Only if the program is called as main script (ie. executed directly ) # dir(itertools) gives a list of all the functions defined in the module # And enumerate(dir(itertools)) allow to loop over that list for i, f in enumerate(filter(lambda s: s[0:2]+s[-2:] != '____', dir(itertools))): # i is an integer, starting fv=f exec("fv=itertools.{}".format(f)) printc("\n\nThe {i}th function of the 'itertools' module is {func}. Its doc is: \n{doc}".format(i=i+1, func=f, doc=fv.__doc__)) # Try to do one example of every itertools # The 1th function of the 'itertools' module is chain. # Its doc: chain(*iterables) -- chain object # # Return a chain object whose .next() method returns elements from the # first iterable until it is exhausted, then elements from the next # iterable, until all of the iterables are exhausted. print itertools.chain.__doc__ print "itertools.chain( xrange(5), 'ABCDEF' ) is an iterable producing 0 1 2 3 4 A B C D E F." for i in itertools.chain( xrange(5), 'ABCDEF' ): print(i) # The 2th function of the 'itertools' module is combinations. # Its doc: combinations(iterable, r) -- combinations object # # Return successive r-length combinations of elements in the iterable. # # combinations(range(4), 3) -- (0,1,2), (0,1,3), (0,2,3), (1,2,3) print itertools.combinations.__doc__ print "itertools.combinations( 'ABCDE', 4 ) is an iterable producing ('A', 'B', 'C', 'D'), ('A', 'B', 'C', 'E'), ('A', 'B', 'D', 'E'), ('A', 'C', 'D', 'E'), ('B', 'C', 'D', 'E')." for i in itertools.combinations( 'ABCDE', 4 ): print(i) # The 3th function of the 'itertools' module is combinations_with_replacement. # Its doc: combinations_with_replacement(iterable, r) -- combinations_with_replacement object # # Return successive r-length combinations of elements in the iterable # allowing individual elements to have successive repeats. # combinations_with_replacement('ABC', 2) -- AA AB AC BB BC CC print itertools.combinations_with_replacement.__doc__ print "itertools.combinations_with_replacement( {1, 2, 3}, 2 ) is an iterable producing (1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)." for i in itertools.combinations_with_replacement( {1, 2, 3}, 2 ): print(i) # The 4th function of the 'itertools' module is compress. # Its doc: compress(data, selectors) -- iterator over selected data # # Return data elements corresponding to true selector elements. # Forms a shorter iterator from selected data elements using the # selectors to choose the data elements. print itertools.compress.__doc__ print "itertools.compress( 'ABCDE', 4 ) is an iterable producing [1, 2, 3, 1, 2, 3], [2,3]." for i in itertools.compress( [1, 2, 3, 1, 2, 3], [2,3] ): print(i) print "?????" # The 5th function of the 'itertools' module is count. # Its doc: count(start=0, step=1) -- count object # # Return a count object whose .next() method returns consecutive values. # Equivalent to: # # def count(firstval=0, step=1): # x = firstval # while 1: # yield x # x += step print itertools.count.__doc__ print "itertools.count( 0, 10 ) is an iterable producing 0, 10, 20, 30, 40, 50, .., 10k, 10k+10, .. infinitely." for i in itertools.count( 0, 10 ): print(i) # This line is necessary for the program to stop! if i > 40: break # The 6th function of the 'itertools' module is cycle. # Its doc: cycle(iterable) -- cycle object # # Return elements from the iterable until it is exhausted. # Then repeat the sequence indefinitely. print itertools.cycle.__doc__ print "itertools.cycle( 'ABCD' ) is an iterable producing A B C D A B C D A B C D .. A B C D infinitely." for i, l in enumerate(itertools.cycle( 'ABCD' )): print("i={}, l={}".format(i,l)) # This line is necessary for the program to stop! if i > 12: break # The 7th function of the 'itertools' module is dropwhile. # Its doc: dropwhile(predicate, iterable) -- dropwhile object # # Drop items from the iterable while predicate(item) is true. # Afterwards, return every element until the iterable is exhausted. print itertools.dropwhile.__doc__ print "itertools.dropwhile( lambda i: i<12, range(20) ) is an iterable producing 12, 13, 14, 15, 16, 17, 18, 19." for i in itertools.dropwhile( lambda i: i<12, range(20) ): print(i) # The 8th function of the 'itertools' module is groupby. # Its doc: groupby(iterable[, keyfunc]) - create an iterator which returns # (key, sub-iterator) grouped by each value of key(value). print itertools.groupby.__doc__ print "itertools.groupby( lambda i: i<12, range(20) ) is an iterable producing 12, 13, 14, 15, 16, 17, 18, 19." for k, sub in itertools.groupby( range(10), lambda k: k % 3 ): print("\nkey={}".format(k)) for i in sub: print(i) print "?????" # The 9th function of the 'itertools' module is ifilter. # Its doc: ifilter(function or None, sequence) -- ifilter object # # Return those items of sequence for which function(item) is true. # If function is None, return the items that are true. # Is like List.filter from OCaml print itertools.ifilter.__doc__ print "itertools.ifilter( lambda i: i%3 == 0, range(20) ) is an iterable producing 0, 3, 6, 9, 12, 15, 18." for i in itertools.ifilter( lambda i: i%3 == 0, range(20) ): print(i) # The 10th function of the 'itertools' module is ifilterfalse. # Its doc: ifilterfalse(function or None, sequence) -- ifilterfalse object # # Return those items of sequence for which function(item) is false. # If function is None, return the items that are false. print itertools.ifilterfalse.__doc__ print "itertools.ifilterfalse( lambda i: i%3 == 0, range(20) ) is an iterable producing 1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19." for i in itertools.ifilterfalse( lambda i: i%3 == 0, range(20) ): print(i) # The 11th function of the 'itertools' module is imap. # Its doc: imap(func, *iterables) -- imap object # # Make an iterator that computes the function using arguments from # each of the iterables. Like map() except that it returns # an iterator instead of a list and that it stops when the shortest # iterable is exhausted instead of filling in None for shorter # iterables. print itertools.imap.__doc__ print "itertools.imap( lambda i,j,k: i*j*k, [0,1,1,1], [1,2,3,4], [2,4,6,8] ) is an iterable producing 0, 8, 18, 32." for i in itertools.imap( lambda i,j,k: i*j*k, [0,1,1,1], [1,2,3,4], [2,4,6,8] ): print(i) # The 12th function of the 'itertools' module is islice. # Its doc: islice(iterable, [start,] stop [, step]) -- islice object # # Return an iterator whose next() method returns selected values from an # iterable. If start is specified, will skip all preceding elements; # otherwise, start defaults to zero. Step defaults to one. If # specified as another value, step determines how many values are # skipped between successive calls. Works like a slice() on a list # but returns an iterator. print itertools.islice.__doc__ print "itertools.islice( range(19), 4, 17, 2 ) is an iterable producing 4, 6, 8, 10, 12, 14, 16." for i in itertools.islice( range(19), 4, 17, 2): print(i) # The 13th function of the 'itertools' module is izip. # Its doc: izip(iter1 [,iter2 [...]]) -- izip object # # Return a izip object whose .next() method returns a tuple where # the i-th element comes from the i-th iterable argument. The .next() # method continues until the shortest iterable in the argument sequence # is exhausted and then it raises StopIteration. Works like the zip() # function but consumes less memory by returning an iterator instead of # a list. print itertools.izip.__doc__ print "itertools.izip( range(19), 'ABCD', {0, 9, 56, -1} ) is an iterable producing (0, 'A' , 0), (1, 'B', 9), (2, 'C', 56), (3, 'D', -1)." for i in itertools.izip( range(19), 'ABCD', {0, 9, 56, -1}): print(i) # The 14th function of the 'itertools' module is izip_longest. # Its doc: izip_longest(iter1 [,iter2 [...]], [fillvalue=None]) -- izip_longest object # # Return an izip_longest object whose .next() method returns a tuple where # the i-th element comes from the i-th iterable argument. The .next() # method continues until the longest iterable in the argument sequence # is exhausted and then it raises StopIteration. When the shorter iterables # are exhausted, the fillvalue is substituted in their place. The fillvalue # defaults to None or can be specified by a keyword argument. # # # # The 15th function of the 'itertools' module is permutations. # Its doc: permutations(iterable[, r]) -- permutations object # # Return successive r-length permutations of elements in the iterable. # # permutations(range(3), 2) -- (0,1), (0,2), (1,0), (1,2), (2,0), (2,1) # # # The 16th function of the 'itertools' module is product. # Its doc: product(*iterables) -- product object # # Cartesian product of input iterables. Equivalent to nested for-loops. # # For example, product(A, B) returns the same as: ((x,y) for x in A for y in B). # The leftmost iterators are in the outermost for-loop, so the output tuples # cycle in a manner similar to an odometer (with the rightmost element changing # on every iteration). # # To compute the product of an iterable with itself, specify the number # of repetitions with the optional repeat keyword argument. For example, # product(A, repeat=4) means the same as product(A, A, A, A). # # product('ab', range(3)) -- ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2) # product((0,1), (0,1), (0,1)) -- (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ... # # # The 17th function of the 'itertools' module is repeat. # Its doc: repeat(object [,times]) - create an iterator which returns the object # for the specified number of times. If not specified, returns the object # endlessly. # # # The 18th function of the 'itertools' module is starmap. # Its doc: starmap(function, sequence) -- starmap object # # Return an iterator whose values are returned from the function evaluated # with a argument tuple taken from the given sequence. # # # The 19th function of the 'itertools' module is takewhile. # Its doc: takewhile(predicate, iterable) -- takewhile object # # Return successive entries from an iterable as long as the # predicate evaluates to true for each entry. # # # The 20th function of the 'itertools' module is tee. # Its doc: tee(iterable, n=2) -- tuple of n independent iterators.