Skip to content

Commit

Permalink
fix groupby should yield tuples of key Seq_T (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinBernstorff authored Jan 1, 2024
2 parents 465814b + 2b4dcd1 commit ad8293b
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 20 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ Other Python projects have had similar ideas:
#### Philosophy
* Make it work: Concise syntax borrowed from Scala, Rust etc.
* Make it right: Fully typed, no exceptions
* Make it fast: Concurrency through `.pmap`, potentially caching in the future
* Make it fast:
* Concurrency through `.pmap`
* (Future): Caching
* (Future): Refactor operations to use generators
* Keep it simple: No dependencies

#### API design
Expand Down
17 changes: 10 additions & 7 deletions functionalpy/_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
Callable,
Iterable,
Iterator,
Mapping,
Sequence,
)
from functools import reduce
Expand Down Expand Up @@ -61,20 +60,24 @@ def reduce(self, func: Callable[[_T, _T], _T]) -> _T:

def groupby(
self, func: Callable[[_T], str]
) -> "Mapping[str, Sequence[_T]]":
mapping: defaultdict[str, list[_T]] = defaultdict(list)
) -> "Seq[tuple[str, list[_T]]]":
groups_with_values: defaultdict[str, list[_T]] = defaultdict(
list
)

for item in self._seq:
mapping[func(item)].append(item)
for value in self._seq:
value_key = func(value)
groups_with_values[value_key].append(value)

return dict(mapping)
tuples = list(groups_with_values.items())
return Seq(tuples)

def flatten(self) -> "Seq[_T]":
values: list[_T] = []

for i in self._seq:
if isinstance(i, Sequence) and not isinstance(i, str):
values.extend(i)
values.extend(i) # type: ignore
else:
values.append(i)

Expand Down
6 changes: 1 addition & 5 deletions functionalpy/_sequence.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,12 @@ from collections.abc import (
Callable,
Iterable,
Iterator,
Mapping,
Sequence,
)
from typing import Generic, TypeVar, overload

_T = TypeVar("_T")
_S = TypeVar("_S")

# TODO: Attempt generic type alias for container types

class Seq(Generic[_T]):
def __init__(self, iterable: Iterable[_T]) -> None: ...
def count(self) -> int: ...
Expand All @@ -31,7 +27,7 @@ class Seq(Generic[_T]):
def reduce(self, func: Callable[[_T, _T], _T]) -> _T: ...
def groupby(
self, func: Callable[[_T], str]
) -> Mapping[str, Sequence[_T]]: ...
) -> Seq[tuple[str, list[_T]]]: ...
@overload
def flatten(self: Seq[list[_S]]) -> Seq[_S]: ...
@overload
Expand Down
2 changes: 1 addition & 1 deletion functionalpy/benchmark/query_1/iterators_q1.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def main_iterator(data: Sequence[Item]) -> Sequence[CategorySummary]:

summaries = [
summarise_category(group, rows=values)
for group, values in mapping.items()
for group, values in mapping.to_iter()
]

return summaries
Expand Down
14 changes: 8 additions & 6 deletions functionalpy/test_sequence.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from collections.abc import Mapping, Sequence
from collections.abc import Sequence
from typing import Literal

from functionalpy._sequence import Seq
Expand Down Expand Up @@ -58,11 +58,13 @@ def is_even(num: int) -> str:
return "even"
return "odd"

grouped: Mapping[str, Sequence[int]] = sequence.groupby(is_even)
assert grouped == {
"odd": [1, 3],
"even": [2, 4],
}
grouped: list[tuple[str, list[int]]] = sequence.groupby(
is_even
).to_list()
assert grouped == [
("odd", [1, 3]),
("even", [2, 4]),
]


def test_flatten():
Expand Down

0 comments on commit ad8293b

Please sign in to comment.