Skip to content

Instantly share code, notes, and snippets.

@vterron
Last active May 17, 2020 18:33
Show Gist options
  • Save vterron/cd600a1361f1ae6513e0c22b3759120d to your computer and use it in GitHub Desktop.
Save vterron/cd600a1361f1ae6513e0c22b3759120d to your computer and use it in GitHub Desktop.
Use itertools.groupby() to split a series of numbers into sub-itervals based on distance to the first element.
#! /usr/bin/env python3
"""Use itertools.groupby() to split a series of numbers into sub-itervals.
For each interval, all its elements satisfy (x_{i} - x_{0}) < WINDOW.
Keys to this approach:
- We need a global variable to keep track of the current x_{0}.
- The key value of each element is x_{0} (so that all the elements fall into the same group).
"""
import itertools
_X0 = None
_WINDOW = 10
numbers = [1, 2, 4, 5, 15, 14, 18, 19, 20, 21, 23, 34, 38, 45]
def check_window(x):
global _X0
if _X0 is None:
_X0 = x
if abs(_X0 - x) >= _WINDOW:
_X0 = x
return _X0
for _, g in itertools.groupby(numbers, key=check_window):
print(list(g))
"""
Mandatory improvement: use a callable class to keep state, instead of global variables.
"""
class WindowChecker:
def __init__(self, window):
self.window = window
self.x0 = None
def __call__(self, x):
if self.x0 is None:
self.x0 = x
if abs(self.x0 - x) >= self.window:
self.x0 = x
return self.x0
for _, g in itertools.groupby(numbers, key=WindowChecker(window=10)):
print(list(g))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment