You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

47 lines
1.3 KiB

4 years ago
  1. import itertools
  2. from .itertoolz import frequencies, pluck, getter
  3. from .compatibility import map
  4. __all__ = ('countby', 'partitionby')
  5. def countby(key, seq):
  6. """ Count elements of a collection by a key function
  7. >>> countby(len, ['cat', 'mouse', 'dog'])
  8. {3: 2, 5: 1}
  9. >>> def iseven(x): return x % 2 == 0
  10. >>> countby(iseven, [1, 2, 3]) # doctest:+SKIP
  11. {True: 1, False: 2}
  12. See Also:
  13. groupby
  14. """
  15. if not callable(key):
  16. key = getter(key)
  17. return frequencies(map(key, seq))
  18. def partitionby(func, seq):
  19. """ Partition a sequence according to a function
  20. Partition `s` into a sequence of lists such that, when traversing
  21. `s`, every time the output of `func` changes a new list is started
  22. and that and subsequent items are collected into that list.
  23. >>> is_space = lambda c: c == " "
  24. >>> list(partitionby(is_space, "I have space"))
  25. [('I',), (' ',), ('h', 'a', 'v', 'e'), (' ',), ('s', 'p', 'a', 'c', 'e')]
  26. >>> is_large = lambda x: x > 10
  27. >>> list(partitionby(is_large, [1, 2, 1, 99, 88, 33, 99, -1, 5]))
  28. [(1, 2, 1), (99, 88, 33, 99), (-1, 5)]
  29. See also:
  30. partition
  31. groupby
  32. itertools.groupby
  33. """
  34. return map(tuple, pluck(1, itertools.groupby(seq, key=func)))