Small improvements to the itertools docs (GH-123885)

This commit is contained in:
Raymond Hettinger 2024-09-09 20:57:49 -05:00 committed by GitHub
parent d359a7683e
commit 2afba5ca6d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 26 additions and 8 deletions

View File

@ -474,7 +474,7 @@ loops that truncate the stream.
If *start* is zero or ``None``, iteration starts at zero. Otherwise, If *start* is zero or ``None``, iteration starts at zero. Otherwise,
elements from the iterable are skipped until *start* is reached. elements from the iterable are skipped until *start* is reached.
If *stop* is ``None``, iteration continues until the iterator is If *stop* is ``None``, iteration continues until the iterable is
exhausted, if at all. Otherwise, it stops at the specified position. exhausted, if at all. Otherwise, it stops at the specified position.
If *step* is ``None``, the step defaults to one. Elements are returned If *step* is ``None``, the step defaults to one. Elements are returned
@ -503,6 +503,10 @@ loops that truncate the stream.
yield element yield element
next_i += step next_i += step
If the input is an iterator, then fully consuming the *islice*
advances the input iterator by ``max(start, stop)`` steps regardless
of the *step* value.
.. function:: pairwise(iterable) .. function:: pairwise(iterable)
@ -601,6 +605,8 @@ loops that truncate the stream.
# product('ABCD', 'xy') → Ax Ay Bx By Cx Cy Dx Dy # product('ABCD', 'xy') → Ax Ay Bx By Cx Cy Dx Dy
# product(range(2), repeat=3) → 000 001 010 011 100 101 110 111 # product(range(2), repeat=3) → 000 001 010 011 100 101 110 111
if repeat < 0:
raise ValueError('repeat argument cannot be negative')
pools = [tuple(pool) for pool in iterables] * repeat pools = [tuple(pool) for pool in iterables] * repeat
result = [[]] result = [[]]
@ -684,6 +690,8 @@ loops that truncate the stream.
Roughly equivalent to:: Roughly equivalent to::
def tee(iterable, n=2): def tee(iterable, n=2):
if n < 0:
raise ValueError('n must be >= 0')
iterator = iter(iterable) iterator = iter(iterable)
shared_link = [None, None] shared_link = [None, None]
return tuple(_tee(iterator, shared_link) for _ in range(n)) return tuple(_tee(iterator, shared_link) for _ in range(n))
@ -703,6 +711,12 @@ loops that truncate the stream.
used anywhere else; otherwise, the *iterable* could get advanced without used anywhere else; otherwise, the *iterable* could get advanced without
the tee objects being informed. the tee objects being informed.
When the input *iterable* is already a tee iterator object, all
members of the return tuple are constructed as if they had been
produced by the upstream :func:`tee` call. This "flattening step"
allows nested :func:`tee` calls to share the same underlying data
chain and to have a single update step rather than a chain of calls.
``tee`` iterators are not threadsafe. A :exc:`RuntimeError` may be ``tee`` iterators are not threadsafe. A :exc:`RuntimeError` may be
raised when simultaneously using iterators returned by the same :func:`tee` raised when simultaneously using iterators returned by the same :func:`tee`
call, even if the original *iterable* is threadsafe. call, even if the original *iterable* is threadsafe.

View File

@ -992,12 +992,16 @@ class TestBasicOps(unittest.TestCase):
else: else:
return return
def product2(*args, **kwds): def product2(*iterables, repeat=1):
'Pure python version used in docs' 'Pure python version used in docs'
pools = list(map(tuple, args)) * kwds.get('repeat', 1) if repeat < 0:
raise ValueError('repeat argument cannot be negative')
pools = [tuple(pool) for pool in iterables] * repeat
result = [[]] result = [[]]
for pool in pools: for pool in pools:
result = [x+[y] for x in result for y in pool] result = [x+[y] for x in result for y in pool]
for prod in result: for prod in result:
yield tuple(prod) yield tuple(prod)
@ -1754,6 +1758,8 @@ class TestPurePythonRoughEquivalents(unittest.TestCase):
# Begin tee() recipe ########################################### # Begin tee() recipe ###########################################
def tee(iterable, n=2): def tee(iterable, n=2):
if n < 0:
raise ValueError('n must be >= 0')
iterator = iter(iterable) iterator = iter(iterable)
shared_link = [None, None] shared_link = [None, None]
return tuple(_tee(iterator, shared_link) for _ in range(n)) return tuple(_tee(iterator, shared_link) for _ in range(n))
@ -1829,11 +1835,9 @@ class TestPurePythonRoughEquivalents(unittest.TestCase):
self.assertEqual(list(a), list(range(100,2000))) self.assertEqual(list(a), list(range(100,2000)))
self.assertEqual(list(c), list(range(2,2000))) self.assertEqual(list(c), list(range(2,2000)))
# Tests not applicable to the tee() recipe # test invalid values of n
if False: self.assertRaises(TypeError, tee, 'abc', 'invalid')
# test invalid values of n self.assertRaises(ValueError, tee, [], -1)
self.assertRaises(TypeError, tee, 'abc', 'invalid')
self.assertRaises(ValueError, tee, [], -1)
for n in range(5): for n in range(5):
result = tee('abc', n) result = tee('abc', n)