import typing
import itertools


def groupby_apply (
    data: typing.Iterable[typing.Any],
    keyfunc: typing.Callable,
    applyfunc: typing.Callable,
    ) -> typing.List[typing.Tuple[typing.Any, typing.Any]]:
    """
GroupBy using a key function and an apply function, without a `pandas`
dependency.
See: <https://docs.python.org/3/library/itertools.html#itertools.groupby>

    data:
iterable

    keyfunc:
callable to define the key by which you want to group

    applyfunc:
callable to apply to the group

    returns:
an iterable with the accumulated values
    """
    data = sorted(data, key=keyfunc)

    accum: typing.List[typing.Tuple[typing.Any, typing.Any]] = [
        (k, applyfunc(g),)
        for k, g in itertools.groupby(data, keyfunc)
        ]

    return accum