summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/itertools.rst29
-rw-r--r--Lib/test/test_itertools.py49
2 files changed, 77 insertions, 1 deletions
diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst
index fd77f99..254e055 100644
--- a/Doc/library/itertools.rst
+++ b/Doc/library/itertools.rst
@@ -837,6 +837,34 @@ which incur interpreter overhead.
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)
@@ -948,4 +976,3 @@ which incur interpreter overhead.
c, n = c*(n-r)//n, n-1
result.append(pool[-1-n])
return tuple(result)
-
diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py
index 4019af0..0cf7eaf 100644
--- a/Lib/test/test_itertools.py
+++ b/Lib/test/test_itertools.py
@@ -2412,6 +2412,40 @@ Samuele
... 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)
@@ -2539,6 +2573,21 @@ True
>>> 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]
+
+>>> all_upper, remainder = before_and_after(str.isupper, 'ABCdEfGhI')
+>>> str.join('', all_upper)
+'ABC'
+>>> str.join('', remainder)
+'dEfGhI'
+
>>> list(powerset([1,2,3]))
[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]