在Python中如何在排序的日期列表中找到所有缺失的日期?
答案 0 :(得分:21)
使用套装
>>> from datetime import date, timedelta
>>> d = [date(2010, 2, 23), date(2010, 2, 24), date(2010, 2, 25),
date(2010, 2, 26), date(2010, 3, 1), date(2010, 3, 2)]
>>> date_set = set(d[0] + timedelta(x) for x in range((d[-1] - d[0]).days))
>>> missing = sorted(date_set - set(d))
>>> missing
[datetime.date(2010, 2, 27), datetime.date(2010, 2, 28)]
>>>
答案 1 :(得分:4)
对日期列表进行排序并对其进行迭代,记住上一个条目。如果前一个和当前条目之间的差异超过一天,则表示您缺少天数。
这是实现它的一种方法:
from datetime import date, timedelta
from itertools import tee, izip
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
b.next()
return izip(a, b)
def missing_dates(dates):
for prev, curr in pairwise(sorted(dates)):
i = prev
while i + timedelta(1) < curr:
i += timedelta(1)
yield i
dates = [ date(2010, 1, 8),
date(2010, 1, 2),
date(2010, 1, 5),
date(2010, 1, 1),
date(2010, 1, 7) ]
for missing in missing_dates(dates):
print missing
输出:
2010-01-03
2010-01-04
2010-01-06
性能为O(n * log(n)),其中n是输入未排序时跨度中的天数。由于您的列表已经排序,它将以O(n)运行。
答案 2 :(得分:2)
>>> from datetime import datetime, timedelta
>>> date_list = [datetime(2010, 2, 23),datetime(2010, 2, 24),datetime(2010, 2, 25),datetime(2010, 2, 26),datetime(2010, 3, 1),datetime(2010, 3, 2)]
>>>
>>> date_set=set(date_list) # for faster membership tests than list
>>> one_day = timedelta(days=1)
>>>
>>> test_date = date_list[0]
>>> missing_dates=[]
>>> while test_date < date_list[-1]:
... if test_date not in date_set:
... missing_dates.append(test_date)
... test_date += one_day
...
>>> print missing_dates
[datetime.datetime(2010, 2, 27, 0, 0), datetime.datetime(2010, 2, 28, 0, 0)]
这也适用于datetime.date
个对象,但OP表示列表为datetime.datetime
个对象
答案 3 :(得分:1)
将日期放在set
中,然后使用datetime.timedelta()
从第一个日期到最后一个日期进行迭代,每次检查集合中的包含。
答案 4 :(得分:1)
使用循环
您需要的导入:
import datetime
from datetime import date, timedelta
假设您有一个名为dates
的排序列表,其中有几个缺失的日期。
首先选择第一个和最后一个日期:
start_date = dates[0]
end_date = dates[len(dates)-1]
要计算这两个日期之间的天数:
numdays = (end_date - start_date).days
创建一个新列表,其中包含在开始日期和结束日期之间的所有日期:
all_dates = []
for x in range (0, (numdays+1)):
all_dates.append(start_date + datetime.timedelta(days = x))
通过使用带范围的for循环并将这些日期添加到dates_missing中,比起检查日期是否在all_dates
中而不是dates
中来。
dates_missing = []
for i in range (0, len(all_dates)):
if (all_dates[i] not in dates):
dates_missing.append(all_dates[i])
else:
pass
现在,您将获得一个名为dates_missing
的列表,其中包含所有缺失的日期。
答案 5 :(得分:0)
import datetime
DAY = datetime.timedelta(days=1)
# missing dates: a list of [start_date, end)
missing = [(d1+DAY, d2) for d1, d2 in zip(dates, dates[1:]) if (d2 - d1) > DAY]
def date_range(start_date, end, step=DAY):
d = start_date
while d < end:
yield d
d += step
missing_dates = [d for d1, d2 in missing for d in date_range(d1, d2)]
答案 6 :(得分:0)
使用列表理解
>>> from datetime import date, timedelta
>>> d = [date(2010, 2, 23),date(2010, 2, 24),date(2010, 2, 25),date(2010, 2, 26),date(2010, 3, 1),date(2010, 3, 2)]
>>> date_set=set(d)
>>> missing = [x for x in (d[0]+timedelta(x) for x in range((d[-1]-d[0]).days)) if x not in date_set]
>>> missing
[datetime.date(2010, 2, 27), datetime.date(2010, 2, 28)]
答案 7 :(得分:0)
在Python中完成此任务的好方法如下。您不必担心效率,除非您的列表中有多年的日期,并且此代码始终需要根据用户交互运行并立即产生输出。
创建一个功能,为您提供从start_date
到end_date
的所有日期。并使用它。
import datetime
def get_dates(start_date, end_date):
span_between_dates = range(end_date - start_date).days
for index in span_between_dates + 1:
# +1 is to make start and end dates inclusive.
yield start_date + datetime.timedelta(index)
my_date_list = ['2017-03-05', '2017-03_07', ...]
# Edit my_date_list as per your requirement.
start_date = min(my_date_list)
end_date = max(my_date_list)
for current_date in get_dates(start_date, end_date)
if date not in my_date_list:
print date
get_dates
函数应该被定义。
my_other_date_list = [] # your other date range
start_date = min(my_date_list)
end_date = max(my_date_list)
for current_date in get_dates(start_date, end_date)
if (date in my_date_range) and (date in my_other_date_list):
print ('overlapping dates between 2 lists:')
print date
elif (date in my_date_range) and (date not in my_other_date_list):
print ('missing dates:')
print date