mirror of https://github.com/python/cpython
Small improvements to the itertools docs (GH-123885)
This commit is contained in:
parent
d359a7683e
commit
2afba5ca6d
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue