@@ -122,15 +122,15 @@ loops that truncate the stream.
122
122
# accumulate([1,2,3,4,5]) → 1 3 6 10 15
123
123
# accumulate([1,2,3,4,5], initial=100) → 100 101 103 106 110 115
124
124
# accumulate([1,2,3,4,5], operator.mul) → 1 2 6 24 120
125
- it = iter(iterable)
125
+ iterator = iter(iterable)
126
126
total = initial
127
127
if initial is None:
128
128
try:
129
- total = next(it )
129
+ total = next(iterator )
130
130
except StopIteration:
131
131
return
132
132
yield total
133
- for element in it :
133
+ for element in iterator :
134
134
total = func(total, element)
135
135
yield total
136
136
@@ -210,9 +210,8 @@ loops that truncate the stream.
210
210
211
211
def chain(*iterables):
212
212
# chain('ABC', 'DEF') → A B C D E F
213
- for it in iterables:
214
- for element in it:
215
- yield element
213
+ for iterable in iterables:
214
+ yield from iterable
216
215
217
216
218
217
.. classmethod :: chain.from_iterable(iterable)
@@ -222,9 +221,8 @@ loops that truncate the stream.
222
221
223
222
def from_iterable(iterables):
224
223
# chain.from_iterable(['ABC', 'DEF']) → A B C D E F
225
- for it in iterables:
226
- for element in it:
227
- yield element
224
+ for iterable in iterables:
225
+ yield from iterable
228
226
229
227
230
228
.. function :: combinations(iterable, r)
@@ -688,24 +686,22 @@ loops that truncate the stream.
688
686
689
687
Return *n * independent iterators from a single iterable.
690
688
691
- The following Python code helps explain what *tee * does (although the actual
692
- implementation is more complex and uses only a single underlying
693
- :abbr: `FIFO ( first-in, first-out ) ` queue)::
689
+ Roughly equivalent to::
694
690
695
691
def tee(iterable, n=2):
696
- it = iter(iterable)
697
- deques = [collections.deque() for i in range(n) ]
698
- def gen(mydeque):
699
- while True:
700
- if not mydeque: # when the local deque is empty
701
- try :
702
- newval = next(it) # fetch a new value and
703
- except StopIteration :
704
- return
705
- for d in deques: # load it to all the deques
706
- d.append(newval)
707
- yield mydeque.popleft()
708
- return tuple(gen(d) for d in deques)
692
+ iterator = iter(iterable)
693
+ empty_link = [None, None] # Singly linked list: [value, link ]
694
+ return tuple(_tee(iterator, empty_link) for _ in range(n))
695
+
696
+ def _tee(iterator, link):
697
+ while True :
698
+ if link[1] is None:
699
+ try :
700
+ link[:] = [next(iterator), [None, None]]
701
+ except StopIteration:
702
+ return
703
+ value, link = link
704
+ yield value
709
705
710
706
Once a :func: `tee ` has been created, the original *iterable * should not be
711
707
used anywhere else; otherwise, the *iterable * could get advanced without
@@ -735,9 +731,9 @@ loops that truncate the stream.
735
731
return
736
732
while True:
737
733
values = []
738
- for i, it in enumerate(iterators):
734
+ for i, iterator in enumerate(iterators):
739
735
try:
740
- value = next(it )
736
+ value = next(iterator )
741
737
except StopIteration:
742
738
num_active -= 1
743
739
if not num_active:
@@ -792,6 +788,7 @@ and :term:`generators <generator>` which incur interpreter overhead.
792
788
.. testcode ::
793
789
794
790
import collections
791
+ import contextlib
795
792
import functools
796
793
import math
797
794
import operator
@@ -934,32 +931,26 @@ and :term:`generators <generator>` which incur interpreter overhead.
934
931
# iter_index('AABCADEAF', 'A') → 0 1 4 7
935
932
seq_index = getattr(iterable, 'index', None)
936
933
if seq_index is None:
937
- # Path for general iterables
938
934
iterator = islice(iterable, start, stop)
939
935
for i, element in enumerate(iterator, start):
940
936
if element is value or element == value:
941
937
yield i
942
938
else:
943
- # Path for sequences with an index() method
944
939
stop = len(iterable) if stop is None else stop
945
940
i = start
946
- try :
941
+ with contextlib.suppress(ValueError) :
947
942
while True:
948
943
yield (i := seq_index(value, i, stop))
949
944
i += 1
950
- except ValueError:
951
- pass
952
945
953
946
def iter_except(func, exception, first=None):
954
947
"Convert a call-until-exception interface to an iterator interface."
955
948
# iter_except(d.popitem, KeyError) → non-blocking dictionary iterator
956
- try :
949
+ with contextlib.suppress(exception) :
957
950
if first is not None:
958
951
yield first()
959
952
while True:
960
953
yield func()
961
- except exception:
962
- pass
963
954
964
955
965
956
The following recipes have a more mathematical flavor:
0 commit comments