This passes your test:
def cluster(items, key_func):
items = sorted(items)
clusters = [[items[0]]]
for item in items[1:]:
cluster = clusters[-1]
last_item = cluster[-1]
if key_func(item, last_item):
cluster.append(item)
else:
clusters.append([item])
return clusters
Where key_func
returns True
if the current and previous items should be part of the same cluster:
>>> cluster([1,48,52,59,89,94,103,147,151,165], lambda curr, prev: curr-prev < 20)
[[1], [48, 52, 59], [89, 94, 103], [147, 151, 165]]
Another possibility would be to modify the "equivalent code" for itertools.groupby()
to likewise take more than one argument for the key function.