Last active
May 17, 2020 18:33
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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