Skip to content

Commit 8439d09

Browse files
[3.13] Misc improvements to the itertools docs (gh-119040) (#119045)
1 parent 87f683e commit 8439d09

File tree

1 file changed

+26
-35
lines changed

1 file changed

+26
-35
lines changed

Doc/library/itertools.rst

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,15 @@ loops that truncate the stream.
122122
# accumulate([1,2,3,4,5]) → 1 3 6 10 15
123123
# accumulate([1,2,3,4,5], initial=100) → 100 101 103 106 110 115
124124
# accumulate([1,2,3,4,5], operator.mul) → 1 2 6 24 120
125-
it = iter(iterable)
125+
iterator = iter(iterable)
126126
total = initial
127127
if initial is None:
128128
try:
129-
total = next(it)
129+
total = next(iterator)
130130
except StopIteration:
131131
return
132132
yield total
133-
for element in it:
133+
for element in iterator:
134134
total = func(total, element)
135135
yield total
136136

@@ -218,9 +218,8 @@ loops that truncate the stream.
218218

219219
def chain(*iterables):
220220
# chain('ABC', 'DEF') → A B C D E F
221-
for it in iterables:
222-
for element in it:
223-
yield element
221+
for iterable in iterables:
222+
yield from iterable
224223

225224

226225
.. classmethod:: chain.from_iterable(iterable)
@@ -230,9 +229,8 @@ loops that truncate the stream.
230229

231230
def from_iterable(iterables):
232231
# chain.from_iterable(['ABC', 'DEF']) → A B C D E F
233-
for it in iterables:
234-
for element in it:
235-
yield element
232+
for iterable in iterables:
233+
yield from iterable
236234

237235

238236
.. function:: combinations(iterable, r)
@@ -696,24 +694,22 @@ loops that truncate the stream.
696694

697695
Return *n* independent iterators from a single iterable.
698696

699-
The following Python code helps explain what *tee* does (although the actual
700-
implementation is more complex and uses only a single underlying
701-
:abbr:`FIFO (first-in, first-out)` queue)::
697+
Roughly equivalent to::
702698

703699
def tee(iterable, n=2):
704-
it = iter(iterable)
705-
deques = [collections.deque() for i in range(n)]
706-
def gen(mydeque):
707-
while True:
708-
if not mydeque: # when the local deque is empty
709-
try:
710-
newval = next(it) # fetch a new value and
711-
except StopIteration:
712-
return
713-
for d in deques: # load it to all the deques
714-
d.append(newval)
715-
yield mydeque.popleft()
716-
return tuple(gen(d) for d in deques)
700+
iterator = iter(iterable)
701+
empty_link = [None, None] # Singly linked list: [value, link]
702+
return tuple(_tee(iterator, empty_link) for _ in range(n))
703+
704+
def _tee(iterator, link):
705+
while True:
706+
if link[1] is None:
707+
try:
708+
link[:] = [next(iterator), [None, None]]
709+
except StopIteration:
710+
return
711+
value, link = link
712+
yield value
717713

718714
Once a :func:`tee` has been created, the original *iterable* should not be
719715
used anywhere else; otherwise, the *iterable* could get advanced without
@@ -743,9 +739,9 @@ loops that truncate the stream.
743739
return
744740
while True:
745741
values = []
746-
for i, it in enumerate(iterators):
742+
for i, iterator in enumerate(iterators):
747743
try:
748-
value = next(it)
744+
value = next(iterator)
749745
except StopIteration:
750746
num_active -= 1
751747
if not num_active:
@@ -800,6 +796,7 @@ and :term:`generators <generator>` which incur interpreter overhead.
800796
.. testcode::
801797

802798
import collections
799+
import contextlib
803800
import functools
804801
import math
805802
import operator
@@ -942,32 +939,26 @@ and :term:`generators <generator>` which incur interpreter overhead.
942939
# iter_index('AABCADEAF', 'A') → 0 1 4 7
943940
seq_index = getattr(iterable, 'index', None)
944941
if seq_index is None:
945-
# Path for general iterables
946942
iterator = islice(iterable, start, stop)
947943
for i, element in enumerate(iterator, start):
948944
if element is value or element == value:
949945
yield i
950946
else:
951-
# Path for sequences with an index() method
952947
stop = len(iterable) if stop is None else stop
953948
i = start
954-
try:
949+
with contextlib.suppress(ValueError):
955950
while True:
956951
yield (i := seq_index(value, i, stop))
957952
i += 1
958-
except ValueError:
959-
pass
960953

961954
def iter_except(func, exception, first=None):
962955
"Convert a call-until-exception interface to an iterator interface."
963956
# iter_except(d.popitem, KeyError) → non-blocking dictionary iterator
964-
try:
957+
with contextlib.suppress(exception):
965958
if first is not None:
966959
yield first()
967960
while True:
968961
yield func()
969-
except exception:
970-
pass
971962

972963

973964
The following recipes have a more mathematical flavor:

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy