# 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], operator.mul) → 1 2 6 24 120
- it = iter(iterable)
+ iterator = iter(iterable)
total = initial
if initial is None:
try:
- total = next(it)
+ total = next(iterator)
except StopIteration:
return
yield total
- for element in it:
+ for element in iterator:
total = func(total, element)
yield total
def chain(*iterables):
# chain('ABC', 'DEF') → A B C D E F
- for it in iterables:
- for element in it:
- yield element
+ for iterable in iterables:
+ yield from iterable
.. classmethod:: chain.from_iterable(iterable)
def from_iterable(iterables):
# chain.from_iterable(['ABC', 'DEF']) → A B C D E F
- for it in iterables:
- for element in it:
- yield element
+ for iterable in iterables:
+ yield from iterable
.. function:: combinations(iterable, r)
Return *n* independent iterators from a single iterable.
- The following Python code helps explain what *tee* does (although the actual
- implementation is more complex and uses only a single underlying
- :abbr:`FIFO (first-in, first-out)` queue)::
+ Roughly equivalent to::
def tee(iterable, n=2):
- it = iter(iterable)
- deques = [collections.deque() for i in range(n)]
- def gen(mydeque):
- while True:
- if not mydeque: # when the local deque is empty
- try:
- newval = next(it) # fetch a new value and
- except StopIteration:
- return
- for d in deques: # load it to all the deques
- d.append(newval)
- yield mydeque.popleft()
- return tuple(gen(d) for d in deques)
+ iterator = iter(iterable)
+ empty_link = [None, None] # Singly linked list: [value, link]
+ return tuple(_tee(iterator, empty_link) for _ in range(n))
+
+ def _tee(iterator, link):
+ while True:
+ if link[1] is None:
+ try:
+ link[:] = [next(iterator), [None, None]]
+ except StopIteration:
+ return
+ value, link = link
+ yield value
Once a :func:`tee` has been created, the original *iterable* should not be
used anywhere else; otherwise, the *iterable* could get advanced without
return
while True:
values = []
- for i, it in enumerate(iterators):
+ for i, iterator in enumerate(iterators):
try:
- value = next(it)
+ value = next(iterator)
except StopIteration:
num_active -= 1
if not num_active:
.. testcode::
import collections
+ import contextlib
import functools
import math
import operator
# iter_index('AABCADEAF', 'A') → 0 1 4 7
seq_index = getattr(iterable, 'index', None)
if seq_index is None:
- # Path for general iterables
iterator = islice(iterable, start, stop)
for i, element in enumerate(iterator, start):
if element is value or element == value:
yield i
else:
- # Path for sequences with an index() method
stop = len(iterable) if stop is None else stop
i = start
- try:
+ with contextlib.suppress(ValueError):
while True:
yield (i := seq_index(value, i, stop))
i += 1
- except ValueError:
- pass
def iter_except(func, exception, first=None):
"Convert a call-until-exception interface to an iterator interface."
# iter_except(d.popitem, KeyError) → non-blocking dictionary iterator
- try:
+ with contextlib.suppress(exception):
if first is not None:
yield first()
while True:
yield func()
- except exception:
- pass
The following recipes have a more mathematical flavor: