mirror of https://github.com/python/cpython
Move doctests to the main docs. Eliminate duplication. Improve coverage. (GH-30869)
This commit is contained in:
parent
96bf84d57a
commit
ee60550e9b
|
@ -1004,3 +1004,241 @@ which incur interpreter overhead.
|
||||||
c, n = c*(n-r)//n, n-1
|
c, n = c*(n-r)//n, n-1
|
||||||
result.append(pool[-1-n])
|
result.append(pool[-1-n])
|
||||||
return tuple(result)
|
return tuple(result)
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
These examples no longer appear in the docs but are guaranteed
|
||||||
|
to keep working.
|
||||||
|
|
||||||
|
>>> amounts = [120.15, 764.05, 823.14]
|
||||||
|
>>> for checknum, amount in zip(count(1200), amounts):
|
||||||
|
... print('Check %d is for $%.2f' % (checknum, amount))
|
||||||
|
...
|
||||||
|
Check 1200 is for $120.15
|
||||||
|
Check 1201 is for $764.05
|
||||||
|
Check 1202 is for $823.14
|
||||||
|
|
||||||
|
>>> import operator
|
||||||
|
>>> for cube in map(operator.pow, range(1,4), repeat(3)):
|
||||||
|
... print(cube)
|
||||||
|
...
|
||||||
|
1
|
||||||
|
8
|
||||||
|
27
|
||||||
|
|
||||||
|
>>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele']
|
||||||
|
>>> for name in islice(reportlines, 3, None, 2):
|
||||||
|
... print(name.title())
|
||||||
|
...
|
||||||
|
Alex
|
||||||
|
Laura
|
||||||
|
Martin
|
||||||
|
Walter
|
||||||
|
Samuele
|
||||||
|
|
||||||
|
>>> from operator import itemgetter
|
||||||
|
>>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3)
|
||||||
|
>>> di = sorted(sorted(d.items()), key=itemgetter(1))
|
||||||
|
>>> for k, g in groupby(di, itemgetter(1)):
|
||||||
|
... print(k, list(map(itemgetter(0), g)))
|
||||||
|
...
|
||||||
|
1 ['a', 'c', 'e']
|
||||||
|
2 ['b', 'd', 'f']
|
||||||
|
3 ['g']
|
||||||
|
|
||||||
|
# Find runs of consecutive numbers using groupby. The key to the solution
|
||||||
|
# is differencing with a range so that consecutive numbers all appear in
|
||||||
|
# same group.
|
||||||
|
>>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
|
||||||
|
>>> for k, g in groupby(enumerate(data), lambda t:t[0]-t[1]):
|
||||||
|
... print(list(map(operator.itemgetter(1), g)))
|
||||||
|
...
|
||||||
|
[1]
|
||||||
|
[4, 5, 6]
|
||||||
|
[10]
|
||||||
|
[15, 16, 17, 18]
|
||||||
|
[22]
|
||||||
|
[25, 26, 27, 28]
|
||||||
|
|
||||||
|
Now, we test all of the itertool recipes
|
||||||
|
|
||||||
|
>>> import operator
|
||||||
|
>>> import collections
|
||||||
|
|
||||||
|
>>> take(10, count())
|
||||||
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
|
|
||||||
|
>>> list(prepend(1, [2, 3, 4]))
|
||||||
|
[1, 2, 3, 4]
|
||||||
|
|
||||||
|
>>> list(enumerate('abc'))
|
||||||
|
[(0, 'a'), (1, 'b'), (2, 'c')]
|
||||||
|
|
||||||
|
>>> list(islice(tabulate(lambda x: 2*x), 4))
|
||||||
|
[0, 2, 4, 6]
|
||||||
|
|
||||||
|
>>> list(tail(3, 'ABCDEFG'))
|
||||||
|
['E', 'F', 'G']
|
||||||
|
|
||||||
|
>>> it = iter(range(10))
|
||||||
|
>>> consume(it, 3)
|
||||||
|
>>> next(it)
|
||||||
|
3
|
||||||
|
>>> consume(it)
|
||||||
|
>>> next(it, 'Done')
|
||||||
|
'Done'
|
||||||
|
|
||||||
|
>>> nth('abcde', 3)
|
||||||
|
'd'
|
||||||
|
|
||||||
|
>>> nth('abcde', 9) is None
|
||||||
|
True
|
||||||
|
|
||||||
|
>>> [all_equal(s) for s in ('', 'A', 'AAAA', 'AAAB', 'AAABA')]
|
||||||
|
[True, True, True, False, False]
|
||||||
|
|
||||||
|
>>> quantify(range(99), lambda x: x%2==0)
|
||||||
|
50
|
||||||
|
|
||||||
|
>>> quantify([True, False, False, True, True])
|
||||||
|
3
|
||||||
|
|
||||||
|
>>> quantify(range(12), pred=lambda x: x%2==1)
|
||||||
|
6
|
||||||
|
|
||||||
|
>>> a = [[1, 2, 3], [4, 5, 6]]
|
||||||
|
>>> list(flatten(a))
|
||||||
|
[1, 2, 3, 4, 5, 6]
|
||||||
|
|
||||||
|
>>> list(repeatfunc(pow, 5, 2, 3))
|
||||||
|
[8, 8, 8, 8, 8]
|
||||||
|
|
||||||
|
>>> import random
|
||||||
|
>>> take(5, map(int, repeatfunc(random.random)))
|
||||||
|
[0, 0, 0, 0, 0]
|
||||||
|
|
||||||
|
>>> list(islice(pad_none('abc'), 0, 6))
|
||||||
|
['a', 'b', 'c', None, None, None]
|
||||||
|
|
||||||
|
>>> list(ncycles('abc', 3))
|
||||||
|
['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']
|
||||||
|
|
||||||
|
>>> dotproduct([1,2,3], [4,5,6])
|
||||||
|
32
|
||||||
|
|
||||||
|
>>> data = [20, 40, 24, 32, 20, 28, 16]
|
||||||
|
>>> list(convolve(data, [0.25, 0.25, 0.25, 0.25]))
|
||||||
|
[5.0, 15.0, 21.0, 29.0, 29.0, 26.0, 24.0, 16.0, 11.0, 4.0]
|
||||||
|
>>> list(convolve(data, [1, -1]))
|
||||||
|
[20, 20, -16, 8, -12, 8, -12, -16]
|
||||||
|
>>> list(convolve(data, [1, -2, 1]))
|
||||||
|
[20, 0, -36, 24, -20, 20, -20, -4, 16]
|
||||||
|
|
||||||
|
>>> list(flatten([('a', 'b'), (), ('c', 'd', 'e'), ('f',), ('g', 'h', 'i')]))
|
||||||
|
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
|
||||||
|
|
||||||
|
>>> import random
|
||||||
|
>>> random.seed(85753098575309)
|
||||||
|
>>> list(repeatfunc(random.random, 3))
|
||||||
|
[0.16370491282496968, 0.45889608687313455, 0.3747076837820118]
|
||||||
|
>>> list(repeatfunc(chr, 3, 65))
|
||||||
|
['A', 'A', 'A']
|
||||||
|
>>> list(repeatfunc(pow, 3, 2, 5))
|
||||||
|
[32, 32, 32]
|
||||||
|
|
||||||
|
>>> list(grouper('abcdefg', 3, fillvalue='x'))
|
||||||
|
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'x', 'x')]
|
||||||
|
|
||||||
|
>>> it = grouper('abcdefg', 3, incomplete='strict')
|
||||||
|
>>> next(it)
|
||||||
|
('a', 'b', 'c')
|
||||||
|
>>> next(it)
|
||||||
|
('d', 'e', 'f')
|
||||||
|
>>> next(it)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValueError: zip() argument 2 is shorter than argument 1
|
||||||
|
|
||||||
|
>>> list(grouper('abcdefg', n=3, incomplete='ignore'))
|
||||||
|
[('a', 'b', 'c'), ('d', 'e', 'f')]
|
||||||
|
|
||||||
|
>>> list(triplewise('ABCDEFG'))
|
||||||
|
[('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E'), ('D', 'E', 'F'), ('E', 'F', 'G')]
|
||||||
|
|
||||||
|
>>> list(sliding_window('ABCDEFG', 4))
|
||||||
|
[('A', 'B', 'C', 'D'), ('B', 'C', 'D', 'E'), ('C', 'D', 'E', 'F'), ('D', 'E', 'F', 'G')]
|
||||||
|
|
||||||
|
>>> list(roundrobin('abc', 'd', 'ef'))
|
||||||
|
['a', 'd', 'e', 'b', 'f', 'c']
|
||||||
|
|
||||||
|
>>> def is_odd(x):
|
||||||
|
... return x % 2 == 1
|
||||||
|
|
||||||
|
>>> evens, odds = partition(is_odd, range(10))
|
||||||
|
>>> list(evens)
|
||||||
|
[0, 2, 4, 6, 8]
|
||||||
|
>>> list(odds)
|
||||||
|
[1, 3, 5, 7, 9]
|
||||||
|
|
||||||
|
>>> it = iter('ABCdEfGhI')
|
||||||
|
>>> all_upper, remainder = before_and_after(str.isupper, it)
|
||||||
|
>>> ''.join(all_upper)
|
||||||
|
'ABC'
|
||||||
|
>>> ''.join(remainder)
|
||||||
|
'dEfGhI'
|
||||||
|
|
||||||
|
>>> list(powerset([1,2,3]))
|
||||||
|
[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
|
||||||
|
|
||||||
|
>>> all(len(list(powerset(range(n)))) == 2**n for n in range(18))
|
||||||
|
True
|
||||||
|
|
||||||
|
>>> list(powerset('abcde')) == sorted(sorted(set(powerset('abcde'))), key=len)
|
||||||
|
True
|
||||||
|
|
||||||
|
>>> list(unique_everseen('AAAABBBCCDAABBB'))
|
||||||
|
['A', 'B', 'C', 'D']
|
||||||
|
|
||||||
|
>>> list(unique_everseen('ABBCcAD', str.lower))
|
||||||
|
['A', 'B', 'C', 'D']
|
||||||
|
|
||||||
|
>>> list(unique_justseen('AAAABBBCCDAABBB'))
|
||||||
|
['A', 'B', 'C', 'D', 'A', 'B']
|
||||||
|
|
||||||
|
>>> list(unique_justseen('ABBCcAD', str.lower))
|
||||||
|
['A', 'B', 'C', 'A', 'D']
|
||||||
|
|
||||||
|
>>> d = dict(a=1, b=2, c=3)
|
||||||
|
>>> it = iter_except(d.popitem, KeyError)
|
||||||
|
>>> d['d'] = 4
|
||||||
|
>>> next(it)
|
||||||
|
('d', 4)
|
||||||
|
>>> next(it)
|
||||||
|
('c', 3)
|
||||||
|
>>> next(it)
|
||||||
|
('b', 2)
|
||||||
|
>>> d['e'] = 5
|
||||||
|
>>> next(it)
|
||||||
|
('e', 5)
|
||||||
|
>>> next(it)
|
||||||
|
('a', 1)
|
||||||
|
>>> next(it, 'empty')
|
||||||
|
'empty'
|
||||||
|
|
||||||
|
>>> first_true('ABC0DEF1', '9', str.isdigit)
|
||||||
|
'0'
|
||||||
|
|
||||||
|
>>> population = 'ABCDEFGH'
|
||||||
|
>>> for r in range(len(population) + 1):
|
||||||
|
... seq = list(combinations(population, r))
|
||||||
|
... for i in range(len(seq)):
|
||||||
|
... assert nth_combination(population, r, i) == seq[i]
|
||||||
|
... for i in range(-len(seq), 0):
|
||||||
|
... assert nth_combination(population, r, i) == seq[i]
|
||||||
|
|
||||||
|
>>> iterable = 'abcde'
|
||||||
|
>>> r = 3
|
||||||
|
>>> combos = list(combinations(iterable, r))
|
||||||
|
>>> all(nth_combination(iterable, r, i) == comb for i, comb in enumerate(combos))
|
||||||
|
True
|
||||||
|
|
|
@ -2321,399 +2321,6 @@ class SizeofTest(unittest.TestCase):
|
||||||
basesize + 10 * self.ssize_t + 4 * self.ssize_t)
|
basesize + 10 * self.ssize_t + 4 * self.ssize_t)
|
||||||
|
|
||||||
|
|
||||||
libreftest = """ Doctest for examples in the library reference: libitertools.tex
|
|
||||||
|
|
||||||
|
|
||||||
>>> amounts = [120.15, 764.05, 823.14]
|
|
||||||
>>> for checknum, amount in zip(count(1200), amounts):
|
|
||||||
... print('Check %d is for $%.2f' % (checknum, amount))
|
|
||||||
...
|
|
||||||
Check 1200 is for $120.15
|
|
||||||
Check 1201 is for $764.05
|
|
||||||
Check 1202 is for $823.14
|
|
||||||
|
|
||||||
>>> import operator
|
|
||||||
>>> for cube in map(operator.pow, range(1,4), repeat(3)):
|
|
||||||
... print(cube)
|
|
||||||
...
|
|
||||||
1
|
|
||||||
8
|
|
||||||
27
|
|
||||||
|
|
||||||
>>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele']
|
|
||||||
>>> for name in islice(reportlines, 3, None, 2):
|
|
||||||
... print(name.title())
|
|
||||||
...
|
|
||||||
Alex
|
|
||||||
Laura
|
|
||||||
Martin
|
|
||||||
Walter
|
|
||||||
Samuele
|
|
||||||
|
|
||||||
>>> from operator import itemgetter
|
|
||||||
>>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3)
|
|
||||||
>>> di = sorted(sorted(d.items()), key=itemgetter(1))
|
|
||||||
>>> for k, g in groupby(di, itemgetter(1)):
|
|
||||||
... print(k, list(map(itemgetter(0), g)))
|
|
||||||
...
|
|
||||||
1 ['a', 'c', 'e']
|
|
||||||
2 ['b', 'd', 'f']
|
|
||||||
3 ['g']
|
|
||||||
|
|
||||||
# Find runs of consecutive numbers using groupby. The key to the solution
|
|
||||||
# is differencing with a range so that consecutive numbers all appear in
|
|
||||||
# same group.
|
|
||||||
>>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
|
|
||||||
>>> for k, g in groupby(enumerate(data), lambda t:t[0]-t[1]):
|
|
||||||
... print(list(map(operator.itemgetter(1), g)))
|
|
||||||
...
|
|
||||||
[1]
|
|
||||||
[4, 5, 6]
|
|
||||||
[10]
|
|
||||||
[15, 16, 17, 18]
|
|
||||||
[22]
|
|
||||||
[25, 26, 27, 28]
|
|
||||||
|
|
||||||
>>> def take(n, iterable):
|
|
||||||
... "Return first n items of the iterable as a list"
|
|
||||||
... return list(islice(iterable, n))
|
|
||||||
|
|
||||||
>>> def prepend(value, iterator):
|
|
||||||
... "Prepend a single value in front of an iterator"
|
|
||||||
... # prepend(1, [2, 3, 4]) -> 1 2 3 4
|
|
||||||
... return chain([value], iterator)
|
|
||||||
|
|
||||||
>>> def enumerate(iterable, start=0):
|
|
||||||
... return zip(count(start), iterable)
|
|
||||||
|
|
||||||
>>> def tabulate(function, start=0):
|
|
||||||
... "Return function(0), function(1), ..."
|
|
||||||
... return map(function, count(start))
|
|
||||||
|
|
||||||
>>> import collections
|
|
||||||
>>> def consume(iterator, n=None):
|
|
||||||
... "Advance the iterator n-steps ahead. If n is None, consume entirely."
|
|
||||||
... # Use functions that consume iterators at C speed.
|
|
||||||
... if n is None:
|
|
||||||
... # feed the entire iterator into a zero-length deque
|
|
||||||
... collections.deque(iterator, maxlen=0)
|
|
||||||
... else:
|
|
||||||
... # advance to the empty slice starting at position n
|
|
||||||
... next(islice(iterator, n, n), None)
|
|
||||||
|
|
||||||
>>> def nth(iterable, n, default=None):
|
|
||||||
... "Returns the nth item or a default value"
|
|
||||||
... return next(islice(iterable, n, None), default)
|
|
||||||
|
|
||||||
>>> def all_equal(iterable):
|
|
||||||
... "Returns True if all the elements are equal to each other"
|
|
||||||
... g = groupby(iterable)
|
|
||||||
... return next(g, True) and not next(g, False)
|
|
||||||
|
|
||||||
>>> def quantify(iterable, pred=bool):
|
|
||||||
... "Count how many times the predicate is true"
|
|
||||||
... return sum(map(pred, iterable))
|
|
||||||
|
|
||||||
>>> def pad_none(iterable):
|
|
||||||
... "Returns the sequence elements and then returns None indefinitely"
|
|
||||||
... return chain(iterable, repeat(None))
|
|
||||||
|
|
||||||
>>> def ncycles(iterable, n):
|
|
||||||
... "Returns the sequence elements n times"
|
|
||||||
... return chain(*repeat(iterable, n))
|
|
||||||
|
|
||||||
>>> def dotproduct(vec1, vec2):
|
|
||||||
... return sum(map(operator.mul, vec1, vec2))
|
|
||||||
|
|
||||||
>>> def flatten(listOfLists):
|
|
||||||
... return list(chain.from_iterable(listOfLists))
|
|
||||||
|
|
||||||
>>> def repeatfunc(func, times=None, *args):
|
|
||||||
... "Repeat calls to func with specified arguments."
|
|
||||||
... " Example: repeatfunc(random.random)"
|
|
||||||
... if times is None:
|
|
||||||
... return starmap(func, repeat(args))
|
|
||||||
... else:
|
|
||||||
... return starmap(func, repeat(args, times))
|
|
||||||
|
|
||||||
>>> def grouper(iterable, n, *, incomplete='fill', fillvalue=None):
|
|
||||||
... "Collect data into non-overlapping fixed-length chunks or blocks"
|
|
||||||
... # grouper('ABCDEFG', 3, fillvalue='x') --> ABC DEF Gxx
|
|
||||||
... # grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError
|
|
||||||
... # grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF
|
|
||||||
... args = [iter(iterable)] * n
|
|
||||||
... if incomplete == 'fill':
|
|
||||||
... return zip_longest(*args, fillvalue=fillvalue)
|
|
||||||
... if incomplete == 'strict':
|
|
||||||
... return zip(*args, strict=True)
|
|
||||||
... if incomplete == 'ignore':
|
|
||||||
... return zip(*args)
|
|
||||||
... else:
|
|
||||||
... raise ValueError('Expected fill, strict, or ignore')
|
|
||||||
|
|
||||||
>>> def triplewise(iterable):
|
|
||||||
... "Return overlapping triplets from an iterable"
|
|
||||||
... # pairwise('ABCDEFG') -> ABC BCD CDE DEF EFG
|
|
||||||
... for (a, _), (b, c) in pairwise(pairwise(iterable)):
|
|
||||||
... yield a, b, c
|
|
||||||
|
|
||||||
>>> import collections
|
|
||||||
>>> def sliding_window(iterable, n):
|
|
||||||
... # sliding_window('ABCDEFG', 4) -> ABCD BCDE CDEF DEFG
|
|
||||||
... it = iter(iterable)
|
|
||||||
... window = collections.deque(islice(it, n), maxlen=n)
|
|
||||||
... if len(window) == n:
|
|
||||||
... yield tuple(window)
|
|
||||||
... for x in it:
|
|
||||||
... window.append(x)
|
|
||||||
... yield tuple(window)
|
|
||||||
|
|
||||||
>>> def roundrobin(*iterables):
|
|
||||||
... "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
|
|
||||||
... # Recipe credited to George Sakkis
|
|
||||||
... pending = len(iterables)
|
|
||||||
... nexts = cycle(iter(it).__next__ for it in iterables)
|
|
||||||
... while pending:
|
|
||||||
... try:
|
|
||||||
... for next in nexts:
|
|
||||||
... yield next()
|
|
||||||
... except StopIteration:
|
|
||||||
... pending -= 1
|
|
||||||
... nexts = cycle(islice(nexts, pending))
|
|
||||||
|
|
||||||
>>> def partition(pred, iterable):
|
|
||||||
... "Use a predicate to partition entries into false entries and true entries"
|
|
||||||
... # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9
|
|
||||||
... t1, t2 = tee(iterable)
|
|
||||||
... return filterfalse(pred, t1), filter(pred, t2)
|
|
||||||
|
|
||||||
>>> def before_and_after(predicate, it):
|
|
||||||
... ''' Variant of takewhile() that allows complete
|
|
||||||
... access to the remainder of the iterator.
|
|
||||||
...
|
|
||||||
... >>> all_upper, remainder = before_and_after(str.isupper, 'ABCdEfGhI')
|
|
||||||
... >>> str.join('', all_upper)
|
|
||||||
... 'ABC'
|
|
||||||
... >>> str.join('', remainder)
|
|
||||||
... 'dEfGhI'
|
|
||||||
...
|
|
||||||
... Note that the first iterator must be fully
|
|
||||||
... consumed before the second iterator can
|
|
||||||
... generate valid results.
|
|
||||||
... '''
|
|
||||||
... it = iter(it)
|
|
||||||
... transition = []
|
|
||||||
... def true_iterator():
|
|
||||||
... for elem in it:
|
|
||||||
... if predicate(elem):
|
|
||||||
... yield elem
|
|
||||||
... else:
|
|
||||||
... transition.append(elem)
|
|
||||||
... return
|
|
||||||
... def remainder_iterator():
|
|
||||||
... yield from transition
|
|
||||||
... yield from it
|
|
||||||
... return true_iterator(), remainder_iterator()
|
|
||||||
|
|
||||||
>>> def powerset(iterable):
|
|
||||||
... "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
|
|
||||||
... s = list(iterable)
|
|
||||||
... return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
|
|
||||||
|
|
||||||
>>> def unique_everseen(iterable, key=None):
|
|
||||||
... "List unique elements, preserving order. Remember all elements ever seen."
|
|
||||||
... # unique_everseen('AAAABBBCCDAABBB') --> A B C D
|
|
||||||
... # unique_everseen('ABBCcAD', str.lower) --> A B C D
|
|
||||||
... seen = set()
|
|
||||||
... seen_add = seen.add
|
|
||||||
... if key is None:
|
|
||||||
... for element in iterable:
|
|
||||||
... if element not in seen:
|
|
||||||
... seen_add(element)
|
|
||||||
... yield element
|
|
||||||
... else:
|
|
||||||
... for element in iterable:
|
|
||||||
... k = key(element)
|
|
||||||
... if k not in seen:
|
|
||||||
... seen_add(k)
|
|
||||||
... yield element
|
|
||||||
|
|
||||||
>>> def unique_justseen(iterable, key=None):
|
|
||||||
... "List unique elements, preserving order. Remember only the element just seen."
|
|
||||||
... # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
|
|
||||||
... # unique_justseen('ABBCcAD', str.lower) --> A B C A D
|
|
||||||
... return map(next, map(itemgetter(1), groupby(iterable, key)))
|
|
||||||
|
|
||||||
>>> def first_true(iterable, default=False, pred=None):
|
|
||||||
... '''Returns the first true value in the iterable.
|
|
||||||
...
|
|
||||||
... If no true value is found, returns *default*
|
|
||||||
...
|
|
||||||
... If *pred* is not None, returns the first item
|
|
||||||
... for which pred(item) is true.
|
|
||||||
...
|
|
||||||
... '''
|
|
||||||
... # first_true([a,b,c], x) --> a or b or c or x
|
|
||||||
... # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x
|
|
||||||
... return next(filter(pred, iterable), default)
|
|
||||||
|
|
||||||
>>> def nth_combination(iterable, r, index):
|
|
||||||
... 'Equivalent to list(combinations(iterable, r))[index]'
|
|
||||||
... pool = tuple(iterable)
|
|
||||||
... n = len(pool)
|
|
||||||
... if r < 0 or r > n:
|
|
||||||
... raise ValueError
|
|
||||||
... c = 1
|
|
||||||
... k = min(r, n-r)
|
|
||||||
... for i in range(1, k+1):
|
|
||||||
... c = c * (n - k + i) // i
|
|
||||||
... if index < 0:
|
|
||||||
... index += c
|
|
||||||
... if index < 0 or index >= c:
|
|
||||||
... raise IndexError
|
|
||||||
... result = []
|
|
||||||
... while r:
|
|
||||||
... c, n, r = c*r//n, n-1, r-1
|
|
||||||
... while index >= c:
|
|
||||||
... index -= c
|
|
||||||
... c, n = c*(n-r)//n, n-1
|
|
||||||
... result.append(pool[-1-n])
|
|
||||||
... return tuple(result)
|
|
||||||
|
|
||||||
|
|
||||||
This is not part of the examples but it tests to make sure the definitions
|
|
||||||
perform as purported.
|
|
||||||
|
|
||||||
>>> take(10, count())
|
|
||||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
||||||
|
|
||||||
>>> list(prepend(1, [2, 3, 4]))
|
|
||||||
[1, 2, 3, 4]
|
|
||||||
|
|
||||||
>>> list(enumerate('abc'))
|
|
||||||
[(0, 'a'), (1, 'b'), (2, 'c')]
|
|
||||||
|
|
||||||
>>> list(islice(tabulate(lambda x: 2*x), 4))
|
|
||||||
[0, 2, 4, 6]
|
|
||||||
|
|
||||||
>>> it = iter(range(10))
|
|
||||||
>>> consume(it, 3)
|
|
||||||
>>> next(it)
|
|
||||||
3
|
|
||||||
>>> consume(it)
|
|
||||||
>>> next(it, 'Done')
|
|
||||||
'Done'
|
|
||||||
|
|
||||||
>>> nth('abcde', 3)
|
|
||||||
'd'
|
|
||||||
|
|
||||||
>>> nth('abcde', 9) is None
|
|
||||||
True
|
|
||||||
|
|
||||||
>>> [all_equal(s) for s in ('', 'A', 'AAAA', 'AAAB', 'AAABA')]
|
|
||||||
[True, True, True, False, False]
|
|
||||||
|
|
||||||
>>> quantify(range(99), lambda x: x%2==0)
|
|
||||||
50
|
|
||||||
|
|
||||||
>>> a = [[1, 2, 3], [4, 5, 6]]
|
|
||||||
>>> flatten(a)
|
|
||||||
[1, 2, 3, 4, 5, 6]
|
|
||||||
|
|
||||||
>>> list(repeatfunc(pow, 5, 2, 3))
|
|
||||||
[8, 8, 8, 8, 8]
|
|
||||||
|
|
||||||
>>> import random
|
|
||||||
>>> take(5, map(int, repeatfunc(random.random)))
|
|
||||||
[0, 0, 0, 0, 0]
|
|
||||||
|
|
||||||
>>> list(islice(pad_none('abc'), 0, 6))
|
|
||||||
['a', 'b', 'c', None, None, None]
|
|
||||||
|
|
||||||
>>> list(ncycles('abc', 3))
|
|
||||||
['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']
|
|
||||||
|
|
||||||
>>> dotproduct([1,2,3], [4,5,6])
|
|
||||||
32
|
|
||||||
|
|
||||||
>>> list(grouper('abcdefg', 3, fillvalue='x'))
|
|
||||||
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'x', 'x')]
|
|
||||||
|
|
||||||
>>> it = grouper('abcdefg', 3, incomplete='strict')
|
|
||||||
>>> next(it)
|
|
||||||
('a', 'b', 'c')
|
|
||||||
>>> next(it)
|
|
||||||
('d', 'e', 'f')
|
|
||||||
>>> next(it)
|
|
||||||
Traceback (most recent call last):
|
|
||||||
...
|
|
||||||
ValueError: zip() argument 2 is shorter than argument 1
|
|
||||||
|
|
||||||
>>> list(grouper('abcdefg', n=3, incomplete='ignore'))
|
|
||||||
[('a', 'b', 'c'), ('d', 'e', 'f')]
|
|
||||||
|
|
||||||
>>> list(triplewise('ABCDEFG'))
|
|
||||||
[('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E'), ('D', 'E', 'F'), ('E', 'F', 'G')]
|
|
||||||
|
|
||||||
>>> list(sliding_window('ABCDEFG', 4))
|
|
||||||
[('A', 'B', 'C', 'D'), ('B', 'C', 'D', 'E'), ('C', 'D', 'E', 'F'), ('D', 'E', 'F', 'G')]
|
|
||||||
|
|
||||||
>>> list(roundrobin('abc', 'd', 'ef'))
|
|
||||||
['a', 'd', 'e', 'b', 'f', 'c']
|
|
||||||
|
|
||||||
>>> def is_odd(x):
|
|
||||||
... return x % 2 == 1
|
|
||||||
|
|
||||||
>>> evens, odds = partition(is_odd, range(10))
|
|
||||||
>>> list(evens)
|
|
||||||
[0, 2, 4, 6, 8]
|
|
||||||
>>> list(odds)
|
|
||||||
[1, 3, 5, 7, 9]
|
|
||||||
|
|
||||||
>>> it = iter('ABCdEfGhI')
|
|
||||||
>>> all_upper, remainder = before_and_after(str.isupper, it)
|
|
||||||
>>> ''.join(all_upper)
|
|
||||||
'ABC'
|
|
||||||
>>> ''.join(remainder)
|
|
||||||
'dEfGhI'
|
|
||||||
|
|
||||||
>>> list(powerset([1,2,3]))
|
|
||||||
[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
|
|
||||||
|
|
||||||
>>> all(len(list(powerset(range(n)))) == 2**n for n in range(18))
|
|
||||||
True
|
|
||||||
|
|
||||||
>>> list(powerset('abcde')) == sorted(sorted(set(powerset('abcde'))), key=len)
|
|
||||||
True
|
|
||||||
|
|
||||||
>>> list(unique_everseen('AAAABBBCCDAABBB'))
|
|
||||||
['A', 'B', 'C', 'D']
|
|
||||||
|
|
||||||
>>> list(unique_everseen('ABBCcAD', str.lower))
|
|
||||||
['A', 'B', 'C', 'D']
|
|
||||||
|
|
||||||
>>> list(unique_justseen('AAAABBBCCDAABBB'))
|
|
||||||
['A', 'B', 'C', 'D', 'A', 'B']
|
|
||||||
|
|
||||||
>>> list(unique_justseen('ABBCcAD', str.lower))
|
|
||||||
['A', 'B', 'C', 'A', 'D']
|
|
||||||
|
|
||||||
>>> first_true('ABC0DEF1', '9', str.isdigit)
|
|
||||||
'0'
|
|
||||||
|
|
||||||
>>> population = 'ABCDEFGH'
|
|
||||||
>>> for r in range(len(population) + 1):
|
|
||||||
... seq = list(combinations(population, r))
|
|
||||||
... for i in range(len(seq)):
|
|
||||||
... assert nth_combination(population, r, i) == seq[i]
|
|
||||||
... for i in range(-len(seq), 0):
|
|
||||||
... assert nth_combination(population, r, i) == seq[i]
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__test__ = {'libreftest' : libreftest}
|
|
||||||
|
|
||||||
def load_tests(loader, tests, pattern):
|
def load_tests(loader, tests, pattern):
|
||||||
tests.addTest(doctest.DocTestSuite())
|
tests.addTest(doctest.DocTestSuite())
|
||||||
return tests
|
return tests
|
||||||
|
|
Loading…
Reference in New Issue