mirror of https://github.com/python/cpython
[3.13] Misc improvements to the itertools docs (gh-119040) (#119045)
This commit is contained in:
parent
87f683e09a
commit
8439d09aa1
|
@ -122,15 +122,15 @@ loops that truncate the stream.
|
||||||
# accumulate([1,2,3,4,5]) → 1 3 6 10 15
|
# accumulate([1,2,3,4,5]) → 1 3 6 10 15
|
||||||
# accumulate([1,2,3,4,5], initial=100) → 100 101 103 106 110 115
|
# accumulate([1,2,3,4,5], initial=100) → 100 101 103 106 110 115
|
||||||
# accumulate([1,2,3,4,5], operator.mul) → 1 2 6 24 120
|
# accumulate([1,2,3,4,5], operator.mul) → 1 2 6 24 120
|
||||||
it = iter(iterable)
|
iterator = iter(iterable)
|
||||||
total = initial
|
total = initial
|
||||||
if initial is None:
|
if initial is None:
|
||||||
try:
|
try:
|
||||||
total = next(it)
|
total = next(iterator)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
return
|
return
|
||||||
yield total
|
yield total
|
||||||
for element in it:
|
for element in iterator:
|
||||||
total = func(total, element)
|
total = func(total, element)
|
||||||
yield total
|
yield total
|
||||||
|
|
||||||
|
@ -218,9 +218,8 @@ loops that truncate the stream.
|
||||||
|
|
||||||
def chain(*iterables):
|
def chain(*iterables):
|
||||||
# chain('ABC', 'DEF') → A B C D E F
|
# chain('ABC', 'DEF') → A B C D E F
|
||||||
for it in iterables:
|
for iterable in iterables:
|
||||||
for element in it:
|
yield from iterable
|
||||||
yield element
|
|
||||||
|
|
||||||
|
|
||||||
.. classmethod:: chain.from_iterable(iterable)
|
.. classmethod:: chain.from_iterable(iterable)
|
||||||
|
@ -230,9 +229,8 @@ loops that truncate the stream.
|
||||||
|
|
||||||
def from_iterable(iterables):
|
def from_iterable(iterables):
|
||||||
# chain.from_iterable(['ABC', 'DEF']) → A B C D E F
|
# chain.from_iterable(['ABC', 'DEF']) → A B C D E F
|
||||||
for it in iterables:
|
for iterable in iterables:
|
||||||
for element in it:
|
yield from iterable
|
||||||
yield element
|
|
||||||
|
|
||||||
|
|
||||||
.. function:: combinations(iterable, r)
|
.. function:: combinations(iterable, r)
|
||||||
|
@ -696,24 +694,22 @@ loops that truncate the stream.
|
||||||
|
|
||||||
Return *n* independent iterators from a single iterable.
|
Return *n* independent iterators from a single iterable.
|
||||||
|
|
||||||
The following Python code helps explain what *tee* does (although the actual
|
Roughly equivalent to::
|
||||||
implementation is more complex and uses only a single underlying
|
|
||||||
:abbr:`FIFO (first-in, first-out)` queue)::
|
|
||||||
|
|
||||||
def tee(iterable, n=2):
|
def tee(iterable, n=2):
|
||||||
it = iter(iterable)
|
iterator = iter(iterable)
|
||||||
deques = [collections.deque() for i in range(n)]
|
empty_link = [None, None] # Singly linked list: [value, link]
|
||||||
def gen(mydeque):
|
return tuple(_tee(iterator, empty_link) for _ in range(n))
|
||||||
while True:
|
|
||||||
if not mydeque: # when the local deque is empty
|
def _tee(iterator, link):
|
||||||
try:
|
while True:
|
||||||
newval = next(it) # fetch a new value and
|
if link[1] is None:
|
||||||
except StopIteration:
|
try:
|
||||||
return
|
link[:] = [next(iterator), [None, None]]
|
||||||
for d in deques: # load it to all the deques
|
except StopIteration:
|
||||||
d.append(newval)
|
return
|
||||||
yield mydeque.popleft()
|
value, link = link
|
||||||
return tuple(gen(d) for d in deques)
|
yield value
|
||||||
|
|
||||||
Once a :func:`tee` has been created, the original *iterable* should not be
|
Once a :func:`tee` has been created, the original *iterable* should not be
|
||||||
used anywhere else; otherwise, the *iterable* could get advanced without
|
used anywhere else; otherwise, the *iterable* could get advanced without
|
||||||
|
@ -743,9 +739,9 @@ loops that truncate the stream.
|
||||||
return
|
return
|
||||||
while True:
|
while True:
|
||||||
values = []
|
values = []
|
||||||
for i, it in enumerate(iterators):
|
for i, iterator in enumerate(iterators):
|
||||||
try:
|
try:
|
||||||
value = next(it)
|
value = next(iterator)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
num_active -= 1
|
num_active -= 1
|
||||||
if not num_active:
|
if not num_active:
|
||||||
|
@ -800,6 +796,7 @@ and :term:`generators <generator>` which incur interpreter overhead.
|
||||||
.. testcode::
|
.. testcode::
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
|
import contextlib
|
||||||
import functools
|
import functools
|
||||||
import math
|
import math
|
||||||
import operator
|
import operator
|
||||||
|
@ -942,32 +939,26 @@ and :term:`generators <generator>` which incur interpreter overhead.
|
||||||
# iter_index('AABCADEAF', 'A') → 0 1 4 7
|
# iter_index('AABCADEAF', 'A') → 0 1 4 7
|
||||||
seq_index = getattr(iterable, 'index', None)
|
seq_index = getattr(iterable, 'index', None)
|
||||||
if seq_index is None:
|
if seq_index is None:
|
||||||
# Path for general iterables
|
|
||||||
iterator = islice(iterable, start, stop)
|
iterator = islice(iterable, start, stop)
|
||||||
for i, element in enumerate(iterator, start):
|
for i, element in enumerate(iterator, start):
|
||||||
if element is value or element == value:
|
if element is value or element == value:
|
||||||
yield i
|
yield i
|
||||||
else:
|
else:
|
||||||
# Path for sequences with an index() method
|
|
||||||
stop = len(iterable) if stop is None else stop
|
stop = len(iterable) if stop is None else stop
|
||||||
i = start
|
i = start
|
||||||
try:
|
with contextlib.suppress(ValueError):
|
||||||
while True:
|
while True:
|
||||||
yield (i := seq_index(value, i, stop))
|
yield (i := seq_index(value, i, stop))
|
||||||
i += 1
|
i += 1
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def iter_except(func, exception, first=None):
|
def iter_except(func, exception, first=None):
|
||||||
"Convert a call-until-exception interface to an iterator interface."
|
"Convert a call-until-exception interface to an iterator interface."
|
||||||
# iter_except(d.popitem, KeyError) → non-blocking dictionary iterator
|
# iter_except(d.popitem, KeyError) → non-blocking dictionary iterator
|
||||||
try:
|
with contextlib.suppress(exception):
|
||||||
if first is not None:
|
if first is not None:
|
||||||
yield first()
|
yield first()
|
||||||
while True:
|
while True:
|
||||||
yield func()
|
yield func()
|
||||||
except exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
The following recipes have a more mathematical flavor:
|
The following recipes have a more mathematical flavor:
|
||||||
|
|
Loading…
Reference in New Issue