## 2012年5月3日 星期四

### [Python Std Library] Numeric and Math Modules : itertools — Iterators for efficient looping

Preface :
New in version 2.3.

itertools.chain(*iterables)
Make an iterator that returns elements from the first iterable until it is exhausted, then proceeds to the next iterable, until all of the iterables are exhausted. Used for treating consecutive sequences as a single sequence. Equivalent to :
1. def chain(*iterables):
2.     # chain('ABC''DEF') --> A B C D E F
3.     for it in iterables:
4.         for element in it:
5.             yield element
>>> iter = itertools.chain([1, 2, 3], ['a', 'b', 'c'])
>>> for i in iter:
... print('i={0}'.format(i))
...
i=1
i=2
i=3
i=a
i=b
i=c

classmethod chain.from_iterable(iterable)
New in version 2.6.
Alternate constructor for chain(). Gets chained inputs from a single iterable argument that is evaluated lazily.

itertools.combinations(iterabler)
New in version 2.6.
Return r length subsequences of elements from the input iterable.

Combinations are emitted in lexicographic sort order. So, if the input iterable is sorted, the combination tuples will be produced in sorted order.

Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeat values in each combination. Equivalent to :
1. def combinations(iterable, r):
2.     # combinations('ABCD'2) --> AB AC AD BC BD CD
3.     # combinations(range(4), 3) --> 012 013 023 123
4.     pool = tuple(iterable)
5.     n = len(pool)
6.     if r > n:
7.         return
8.     indices = range(r)
9.     yield tuple(pool[i] for i in indices)
10.     while True:
11.         for i in reversed(range(r)):
12.             if indices[i] != i + n - r:
13.                 break
14.         else:
15.             return
16.         indices[i] += 1
17.         for j in range(i+1, r):
18.             indices[j] = indices[j-1] + 1
19.         yield tuple(pool[i] for i in indices)
The code for combinations() can be also expressed as a subsequence of permutations() after filtering entries where the elements are not in sorted order (according to their position in the input pool) :
1. def combinations(iterable, r):
2.     pool = tuple(iterable)
3.     n = len(pool)
4.     for indices in permutations(range(n), r):
5.         if sorted(indices) == list(indices):
6.             yield tuple(pool[i] for i in indices)
The number of items returned is n! /( r! (n-r)!) when n is the size of iterable

itertools.combinations_with_replacement(iterabler)
New in version 2.7.
Return r length subsequences of elements from the input iterable allowing individual elements to be repeated more than once.
Combinations are emitted in lexicographic sort order. So, if the input iterable is sorted, the combination tuples will be produced in sorted order.
Elements are treated as unique based on their position, not on their value. So if the input elements are unique, the generated combinations will also be unique.

itertools.compress(dataselectors)
New in version 2.7.
Make an iterator that filters elements from data returning only those that have a corresponding element in selectors that evaluates to True. Stops when either the data or selectors iterables has been exhausted. Example as below :

itertools.count(start=0, step=1)
Changed in version 2.7: added step argument and allowed non-integer arguments.
Make an iterator that returns evenly spaced values starting with start. Often used as an argument to imap() to generate consecutive data points. Also, used withizip() to add sequence numbers. Example :

itertools.cycle(iterable)
Make an iterator returning elements from the iterable and saving a copy of each. When the iterable is exhausted, return elements from the saved copy. Repeats indefinitely. Example :

itertools.dropwhile(predicateiterable)
Make an iterator that drops elements from the iterable as long as the predicate is true; afterwards, returns every element. Note, the iterator does not produce any output until the predicate first becomes false, so it may have a lengthy start-up time. Example :

itertools.groupby(iterable[, key])
New in version 2.4.
Make an iterator that returns consecutive keys and groups from the iterable. The key is a function computing a key value for each element. If not specified or is None,key defaults to an identity function and returns the element unchanged. Generally, the iterable needs to already be sorted on the same key function.

The returned group is itself an iterator that shares the underlying iterable with groupby(). Because the source is shared, when the groupby() object is advanced, the previous group is no longer visible. So, if that data is needed later, it should be stored as a list. Below is a usage example :

itertools.filterfalse(predicateiterable)
Make an iterator that filters elements from iterable returning only those for which the predicate is False. If predicate is None, return the items that are false. The usage example as below :

itertools.islice(iterable[, start], stop[, step])
Changed in version 2.5: accept None values for default start and step.
Make an iterator that returns selected elements from the iterable. If start is non-zero, then elements from the iterable are skipped until start is reached. Afterward, elements are returned consecutively unless step is set higher than one which results in items being skipped. If stop is None, then iteration continues until the iterator is exhausted, if at all; otherwise, it stops at the specified position. Unlike regular slicing, islice() does not support negative values for startstop, or step.

If start is None, then iteration starts at zero. If step is None, then the step defaults to one. Below is the usage example :

itertools.zip_longest(*iterables[, fillvalue])
New in version 2.6.
Make an iterator that aggregates elements from each of the iterables. If the iterables are of uneven length, missing values are filled-in with fillvalue. Iteration continues until the longest iterable is exhausted. If not specified, fillvalue defaults to None. Usage example as below :

itertools.permutations(iterable[, r])
New in version 2.6.
Return successive r length permutations of elements in the iterable.

If r is not specified or is None, then r defaults to the length of the iterable and all possible full-length permutations are generated.

Permutations are emitted in lexicographic sort order. So, if the input iterable is sorted, the permutation tuples will be produced in sorted order.

itertools.product(*iterables[, repeat])
New in version 2.6.
Cartesian product of input iterables.

Equivalent to nested for-loops in a generator expression. For example, product(A, B) returns the same as ((x,y) for x in A for y in B).

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). Below is the usage example :

itertools.repeat(object[, times])
Make an iterator that returns object over and over again. Runs indefinitely unless the times argument is specified :

itertools.starmap(functioniterable)
Changed in version 2.6: Previously, starmap() required the function arguments to be tuples. Now, any iterable is allowed.
Make an iterator that computes the function using arguments obtained from the iterable.

itertools.takewhile(predicateiterable)
Make an iterator that returns elements from the iterable as long as the predicate is true :

itertools.tee(iterable[, n=2])
New in version 2.4.
Return n independent iterators from a single iterable.

Supplement :
Recipes of itertools
This section shows recipes for creating an extended toolset using the existing itertools as building blocks...

## 關於我自己

Where there is a will, there is a way!