将连续日期与 Python 组合在一起 [英] Group consecutive dates together with Python
本文介绍了将连续日期与 Python 组合在一起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
鉴于:
dates = [
datetime(2014, 10, 11),
datetime(2014, 10, 1),
datetime(2014, 10, 2),
datetime(2014, 10, 3),
datetime(2014, 10, 5),
datetime(2014, 10, 5),
datetime(2014, 10, 6),
datetime(2014, 10, 22),
datetime(2014, 10, 20),
datetime(2014, 10, 21),
datetime(2014, 10, 9),
datetime(2014, 10, 7),
datetime(2014, 10, 6)
]
预期输出:
expect = [
[datetime(2014, 10, 1), datetime(2014, 10, 3)],
[datetime(2014, 10, 5), datetime(2014, 10, 7)],
datetime(2014, 10, 9),
datetime(2014, 10, 11),
[datetime(2014, 10, 20), datetime(2014, 10, 22)]
]
在 Python 中的实现:
from datetime import datetime, timedelta
def parse_date_ranges(dates):
if(not dates or not len(dates) > 0):
return False
# make sure to order dates
dates.sort()
# init values
result = []
tupl = [dates[0], dates[0]]
it = iter(dates)
date = True
def add_tuple_to_result(tuple):
# if first part of tuple differs from last part -> add full tuple
# else -> add first part of tuple only
result.append(tupl if tupl[0] != tupl[1] else tupl[0])
while date:
# get next date or False if no next date
date = next(it, False)
# filter double dates
if(date in tupl):
continue
elif(date):
if(date - timedelta(days=1) == tupl[1]):
# consecutive date, so add date to end of current tuple
tupl[1] = date
else:
# gap larger than 1 day: add current tuple to result
# and create new tuple
add_tuple_to_result(tupl)
tupl = [date, date]
else:
# date == false, so this is the last step.
# add the current tuple to result
add_tuple_to_result(tupl)
return result
有关更多测试,请参阅 https://gist.github.com/mattes/8987332,也是.
See https://gist.github.com/mattes/8987332 for some more tests, too.
问题
该实现有效,但我是 Python 新手.所以我想知道是否有更好的方法来解决这个问题?还是刚刚好?
The implementation works, but I am new to Python. So I was wondering if there are better ways to solve this issue? Or is it just fine?
推荐答案
我喜欢 itertools:
from itertools import tee, zip_longest
from datetime import datetime, timedelta
one_day = timedelta(days=1)
def pairwise(iterable):
a, b = tee(iterable)
next(b, None)
return zip_longest(a, b, fillvalue=None)
def collapse_ranges(sorted_iterable, inc):
pairs = pairwise(sorted_iterable)
for start, tmp in pairs:
if inc(start) == tmp:
for end, tmp in pairs:
if inc(end) != tmp:
break
yield start, end
else:
yield start
# dates = [...]
numbers = [11, 1, 2, 3, 5, 5, 6, 22, 20, 21, 9, 7, 6]
if __name__ == '__main__':
import pprint
for each in collapse_ranges(sorted(set(dates)), lambda d: d + one_day):
pprint.pprint(each)
for each in collapse_ranges(sorted(set(numbers)), (1).__add__):
pprint.pprint(each)
结果:
(datetime.datetime(2014, 10, 1, 0, 0), datetime.datetime(2014, 10, 3, 0, 0))
(datetime.datetime(2014, 10, 5, 0, 0), datetime.datetime(2014, 10, 7, 0, 0))
datetime.datetime(2014, 10, 9, 0, 0)
datetime.datetime(2014, 10, 11, 0, 0)
(datetime.datetime(2014, 10, 20, 0, 0), datetime.datetime(2014, 10, 22, 0, 0))
(1, 3)
(5, 7)
9
11
(20, 22)
这篇关于将连续日期与 Python 组合在一起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文