Reputation: 3670
I read a lot of lower and upper limits from text files and want to merge these limits. The data type is either float number or date string as yyyy-mm-dd
(two independent cases).
Here, a short list of int boundaries, is just a simplified example for demonstration.
# boundaries read from text files.
b = [[-1, 2], [-2, 1], [0, 4], [3, 5], [-3, 1], [-10, -7], [6, 8]]
It's simple if only the lowest and highest limits are wanted.
b = reduce(lambda x,y: [min(x[0], y[0]), max(x[1], y[1]], b)
But there are gaps in the data so that I need to get the gaps also. I expect results like
# return a list merged limits
[[-10, -7], [-3, 5], [6, 8]]
or
# return the limits and list of gaps
[-10, 8], [[-7, -3], [5, 6]]
How can I do that elegantly?
Upvotes: 0
Views: 49
Reputation: 3481
If you like using reduce
, you can still do it this way:
from functools import reduce
def join(acc, v):
if not acc:
return [v]
last = acc.pop()
if v[0] > last[1]:
return acc + [last, v]
return acc + [(last[0], max(last[1], v[1]))]
b = [[-1, 2], [-2, 1], [0, 4], [3, 5], [-3, 1], [-10, -7], [6, 8]]
print(reduce(join, sorted(b), []))
which outputs
[[-10, -7], (-3, 5), [6, 8]]
Upvotes: 1
Reputation: 36043
b = [[-1, 2], [-2, 1], [0, 4], [3, 5], [-3, 1], [-10, -7], [6, 8]]
b.sort()
result = []
current = b[0]
for interval in b[1:]:
if current[1] >= interval[0]:
current[1] = interval[1]
else:
result.append(current)
current = interval
result.append(current)
print(result) # [[-10, -7], [-3, 5], [6, 8]]
Upvotes: 1