我对主题的细微改动(我最初构建了开始/结束列表并将它们压缩以返回元组,但我更喜欢@Karl Knechtel 的生成器方法):
from datetime import date, timedelta
ONE_DAY = timedelta(days=1)
def find_date_windows(dates):
# guard against getting empty list
if not dates:
return
# convert strings to sorted list of datetime.dates
dates = sorted(date(*map(int,d.split('-'))) for d in dates)
# build list of window starts and matching ends
lastStart = lastEnd = dates[0]
for d in dates[1:]:
if d-lastEnd > ONE_DAY:
yield {'start_date':lastStart, 'end_date':lastEnd}
lastStart = d
lastEnd = d
yield {'start_date':lastStart, 'end_date':lastEnd}
以下是测试用例:
tests = [
['2011-02-27', '2011-02-28', '2011-03-01', '2011-04-12', '2011-04-13', '2011-06-08'],
['2011-06-08'],
[],
['2011-02-27', '2011-02-28', '2011-03-01', '2011-04-12', '2011-04-13', '2011-06-08', '2011-06-10'],
]
for dates in tests:
print dates
for window in find_date_windows(dates):
print window
print
印刷:
['2011-02-27', '2011-02-28', '2011-03-01', '2011-04-12', '2011-04-13', '2011-06-08']
{'start_date': datetime.date(2011, 2, 27), 'end_date': datetime.date(2011, 3, 1)}
{'start_date': datetime.date(2011, 4, 12), 'end_date': datetime.date(2011, 4, 13)}
{'start_date': datetime.date(2011, 6, 8), 'end_date': datetime.date(2011, 6, 8)}
['2011-06-08']
{'start_date': datetime.date(2011, 6, 8), 'end_date': datetime.date(2011, 6, 8)}
[]
['2011-02-27', '2011-02-28', '2011-03-01', '2011-04-12', '2011-04-13', '2011-06-08', '2011-06-10']
{'start_date': datetime.date(2011, 2, 27), 'end_date': datetime.date(2011, 3, 1)}
{'start_date': datetime.date(2011, 4, 12), 'end_date': datetime.date(2011, 4, 13)}
{'start_date': datetime.date(2011, 6, 8), 'end_date': datetime.date(2011, 6, 8)}
{'start_date': datetime.date(2011, 6, 10), 'end_date': datetime.date(2011, 6, 10)}