4

I have some interesting using cases in my Ruby code that I want to convert to Python. I think we can leverage in any lib, I mainly use pandas and numpy.

For instance, imagine that you have an array of timed events, these events have a timestamp and another properties (an object or a tuple).

I want a list/array of groups, where these groups are "contiguous" events, with a grace period of g units (in this case, time units).

In my Ruby code I use something like this:

grouped_events = events.chunk_while do |previous_event, next_event|
   next_event.timestamp <= previous_event.timestamp + grace_period
end

Since I'm not using only in timed events, but with anything that I can sort (so they're comparable somehow), I ask: there's a generic way, or a known lib that does this?

Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
rdlu
  • 630
  • 6
  • 10
  • Do you mean to say that you like to group consecutive items (in the array), as long as each next item is less than `g` time away? – 9769953 Oct 09 '18 at 14:15
  • There are quite a few options here: https://stackoverflow.com/questions/4002598/python-list-how-to-read-the-previous-element-when-using-for-loop – maxm Oct 09 '18 at 14:21
  • @9769953 not only g time away, any comparison between two consecutive elements (usually ordered). Time is just "easier" to think. – rdlu Oct 09 '18 at 17:34

1 Answers1

6

Python doesn't have an equivalent function. You'll have to write your own.

Here's my implementation, using an iterator and the yield statement:

def chunk_while(iterable, predicate):
    itr = iter(iterable)

    try:
        prev_value = next(itr)
    except StopIteration:
        # if the iterable is empty, yield nothing
        return

    chunk = [prev_value]
    for value in itr:
        # if the predicate returns False, start a new chunk
        if not predicate(prev_value, value):
            yield chunk
            chunk = []

        chunk.append(value)
        prev_value = value

    # don't forget to yield the final chunk
    if chunk:
        yield chunk

Which can be used like so:

>>> list(chunk_while([1, 3, 2, 5, 5], lambda prev, next_: next_ <= prev + 2))
[[1, 3, 2], [5, 5]]
Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
  • Nice. I was expecting some more of these utility functions for sets, lists, etc, on some unknown lib for me. I think I need to write some extra code, for other things that I also want. Thanks for your contribution. I will test and mark green after that. – rdlu Oct 09 '18 at 17:27