Я нашел ключ к своему решению во втором посте и сложил его вместе.
В моем выпуске есть две части:
- Как мне представить список дат эффективным образом
Ответ: { ссылка }
pto = [
'2020-01-03',
'2020-01-08',
'2020-01-02',
'2020-01-07',
'2020-01-01',
'2020-01-06'
]
ordinal_dates = [datetime.datetime.strptime(i, '%Y-%m-%d').toordinal() for i in pto]
Получив список дат в целочисленном представлении, вы можете просто искать последовательные целые числа и получать верхнюю и нижнюю границы каждого диапазона, а затем преобразовывать обратно в формат гггг-мм-дд.
Ответ: { ссылка }
def ranges(nums):
nums = sorted(set(nums))
gaps = [[s, e] for s, e in zip(nums, nums[1:]) if s+1 < e]
edges = iter(nums[:1] + sum(gaps, []) + nums[-1:])
return list(zip(edges, edges))
Моя полная функция:
def get_date_ranges(pto_list: list) -> list:
pto_dates = [datetime.datetime.strptime(i, '%Y-%m-%d').toordinal() for i in pto_list]
nums = sorted(set(pto_dates))
gaps = [[s, e] for s, e in zip(nums, nums[1:]) if s + 1 < e]
edges = iter(nums[:1] + sum(gaps, []) + nums[-1:])
ordinal_ranges = list(zip(edges, edges))
date_bounds = []
for start, end in ordinal_ranges:
date_bounds.append((
datetime.datetime.fromordinal(start).strftime('%Y-%m-%d'),
datetime.datetime.fromordinal(end).strftime('%Y-%m-%d')
))
return date_bounds