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

1import operator 

2from collections.abc import Callable, Iterable, Iterator 

3from itertools import groupby, repeat 

4from typing import Any 

5 

6from toolz import itertoolz 

7 

8from ..typing import Comparable 

9from .common import iter_to_seq # noqa: F401 

10 

11 

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 ] 

26 

27 

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)) 

34 

35 

36def decompress[T](data: Iterable[tuple[T, int]]) -> Iterable[T]: 

37 for k, n in data: 

38 yield from repeat(k, n) 

39 

40 

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) 

46 

47 curr: T | None = next(seq, None) 

48 if curr is None: 

49 return 

50 

51 yield curr 

52 

53 prev: T = curr 

54 for curr in seq: 

55 yield op(curr, prev) 

56 

57 prev = curr 

58 

59 

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) 

65 

66 curr: T | None = next(seq, None) 

67 if curr is None: 

68 return 

69 

70 yield curr 

71 

72 prev: T = curr 

73 for curr in seq: 

74 res: T = op(prev, curr) 

75 yield res 

76 

77 prev = res