@@ -680,6 +680,14 @@ loops that truncate the stream.
680680 else:
681681 break
682682
683+ Note, the element that first fails the predicate condition is
684+ consumed from the input iterator and there is no way to access it.
685+ This could be an issue if an application wants to further consume the
686+ input iterator after takewhile has been run to exhaustion. To work
687+ around this problem, consider using `more-iterools before_and_after()
688+ <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.before_and_after> `_
689+ instead.
690+
683691
684692.. function :: tee(iterable, n=2)
685693
@@ -996,32 +1004,6 @@ which incur interpreter overhead.
9961004 except exception:
9971005 pass
9981006
999- def before_and_after(predicate, it):
1000- """ Variant of takewhile() that allows complete
1001- access to the remainder of the iterator.
1002-
1003- >>> it = iter (' ABCdEfGhI' )
1004- >>> all_upper, remainder = before_and_after(str .isupper, it)
1005- >>> ' ' .join(all_upper)
1006- 'ABC'
1007- >>> ' ' .join(remainder) # takewhile() would lose the 'd'
1008- 'dEfGhI'
1009-
1010- Note that the true iterator must be fully consumed
1011- before the remainder iterator can generate valid results.
1012- """
1013- it = iter(it)
1014- transition = []
1015-
1016- def true_iterator():
1017- for elem in it:
1018- if predicate(elem):
1019- yield elem
1020- else:
1021- transition.append(elem)
1022- return
1023-
1024- return true_iterator(), chain(transition, it)
10251007
10261008
10271009The following recipes have a more mathematical flavor:
@@ -1531,13 +1513,6 @@ The following recipes have a more mathematical flavor:
15311513 >>> list (odds)
15321514 [1, 3, 5, 7, 9]
15331515
1534- >>> it = iter (' ABCdEfGhI' )
1535- >>> all_upper, remainder = before_and_after(str .isupper, it)
1536- >>> ' ' .join(all_upper)
1537- 'ABC'
1538- >>> ' ' .join(remainder)
1539- 'dEfGhI'
1540-
15411516 >>> list (subslices(' ABCD' ))
15421517 ['A', 'AB', 'ABC', 'ABCD', 'B', 'BC', 'BCD', 'C', 'CD', 'D']
15431518
@@ -1628,6 +1603,32 @@ The following recipes have a more mathematical flavor:
16281603 result.append(pool[-1-n])
16291604 return tuple(result)
16301605
1606+ def before_and_after(predicate, it):
1607+ """ Variant of takewhile() that allows complete
1608+ access to the remainder of the iterator.
1609+
1610+ >>> it = iter (' ABCdEfGhI' )
1611+ >>> all_upper, remainder = before_and_after(str .isupper, it)
1612+ >>> ' ' .join(all_upper)
1613+ 'ABC'
1614+ >>> ' ' .join(remainder) # takewhile() would lose the 'd'
1615+ 'dEfGhI'
1616+
1617+ Note that the true iterator must be fully consumed
1618+ before the remainder iterator can generate valid results.
1619+ """
1620+ it = iter(it)
1621+ transition = []
1622+
1623+ def true_iterator():
1624+ for elem in it:
1625+ if predicate(elem):
1626+ yield elem
1627+ else:
1628+ transition.append(elem)
1629+ return
1630+
1631+ return true_iterator(), chain(transition, it)
16311632
16321633.. doctest ::
16331634 :hide:
@@ -1657,3 +1658,10 @@ The following recipes have a more mathematical flavor:
16571658 >>> combos = list (combinations(iterable, r))
16581659 >>> all (nth_combination(iterable, r, i) == comb for i, comb in enumerate (combos))
16591660 True
1661+
1662+ >>> it = iter (' ABCdEfGhI' )
1663+ >>> all_upper, remainder = before_and_after(str .isupper, it)
1664+ >>> ' ' .join(all_upper)
1665+ 'ABC'
1666+ >>> ' ' .join(remainder)
1667+ 'dEfGhI'
0 commit comments