Python: itertools
groupby:
import typing, operator, itertools class GroupBy: def __init__(self, iterable: typing.Iterable, key=None): if key is None: key = lambda v: v self.key = key self.it = iter(iterable) self.current_key = self.target_key = self.current_value = object() def __iter__(self): return self def __next__(self): self.id = object() while self.current_key == self.target_key: # advance to next group self.current_value = next(self.it) # exit on StopIteration self.current_key = self.key(self.current_value) self.target_key = self.current_key # pass to _grouper, mark the end return self.current_key, self._grouper(self.target_key, self.id) def _grouper(self, target_key, id): while self.id is id and self.current_key == self.target_key: yield self.current_value try: self.current_value = next(self.it) except StopIteration: return self.current_key = self.key(self.current_value) it = GroupBy('AAaABBBCCDAABBB') for k, g in it: print(k, list(g)) print('~' * 80) it = GroupBy('AAaABBBCCDAABBB', key=lambda v: v.upper()) for k, g in it: print(k, list(g)) print('~' * 80) it = GroupBy(sorted('AAaABBBCCDAABBB', key=lambda v: v.upper()), key=lambda v: v.upper()) for k, g in it: print(k, list(g))
islice:
import sys import typing, operator, itertools def islice(iterable, *args): s = slice(*args) start, stop, step = s.start or 0, s.stop or sys.maxsize, s.step or 1 it = iter(range(start, stop, step)) try: nexti = next(it) except StopIteration: # consume iterable up to the start position for i, element in zip(range(start), iterable): pass return try: for i, element in enumerate(iterable): if i == nexti: yield element nexti = next(it) except StopIteration: # only next(it) can trigger StopIteration # consume gap between i & stop, because step > 1 for i, element in zip(range(i + 1, stop), iterable): pass islice(None, 2, None)
pairwise, triplewise, quadwise, sliding_window
import collections import itertools, typing import operator def pairwise(iterable): a, b = itertools.tee(iterable, 2) next(b, None) return zip(a, b) print(list(pairwise('abcd'))) def tripewise(iterable): for (a, _), (b, c) in pairwise(pairwise(iterable)): yield a, b, c print(list(tripewise('abcd'))) def quadwise(iterable): for (a, _, _), (b, c, d) in pairwise(tripewise(iterable)): yield a, b, c, d print(list(quadwise('abcdef'))) def sliding_window(iterable, n): it = iter(iterable) deque = collections.deque(itertools.islice(it, n), maxlen=n) if len(deque) == n: yield tuple(deque) for v in it: deque.append(v) yield tuple(deque) print(list(sliding_window('abcdef', 4)))

浙公网安备 33010602011771号