Coverage for src/extratools_core/seq/__init__.py: 0%
36 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-05 19:38 -0700
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-05 19:38 -0700
1import operator
2from collections.abc import Callable, Iterable, Iterator
3from itertools import groupby, repeat
4from typing import Any
6from toolz import itertoolz
8from ..typing import Comparable
9from .common import iter_to_seq # noqa: F401
12def sorted_by_rank[T](
13 data: Iterable[T],
14 ranks: Iterable[Comparable],
15 *,
16 _reverse: bool = False,
17) -> list[T]:
18 return [
19 v
20 for v, _ in sorted(
21 zip(data, ranks, strict=True),
22 key=lambda x: x[1],
23 reverse=_reverse,
24 )
25 ]
28def compress[T](
29 data: Iterable[T],
30 key: Callable[[T], Any] | None = None,
31) -> Iterable[tuple[T, int]]:
32 for k, g in groupby(data, key=key):
33 yield (k, itertoolz.count(g))
36def decompress[T](data: Iterable[tuple[T, int]]) -> Iterable[T]:
37 for k, n in data:
38 yield from repeat(k, n)
41def to_deltas[T](
42 data: Iterable[T],
43 op: Callable[[T, T], T] = operator.sub,
44) -> Iterable[T]:
45 seq: Iterator[T] = iter(data)
47 curr: T | None = next(seq, None)
48 if curr is None:
49 return
51 yield curr
53 prev: T = curr
54 for curr in seq:
55 yield op(curr, prev)
57 prev = curr
60def from_deltas[T](
61 data: Iterable[T],
62 op: Callable[[T, T], T] = operator.add,
63) -> Iterable[T]:
64 seq: Iterator[T] = iter(data)
66 curr: T | None = next(seq, None)
67 if curr is None:
68 return
70 yield curr
72 prev: T = curr
73 for curr in seq:
74 res: T = op(prev, curr)
75 yield res
77 prev = res