代码之家  ›  专栏  ›  技术社区  ›  Vishal

如何在排序日期列表中查找缺少的日期?

  •  11
  • Vishal  · 技术社区  · 16 年前

    在Python中,如何在已排序的日期列表中查找所有缺少的日期?

    7 回复  |  直到 16 年前
        1
  •  30
  •   John La Rooy    10 年前

    使用集合

    >>> 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)]
    >>> 
    
        2
  •  4
  •   Mark Byers    16 年前

    对日期列表排序并迭代,记住上一个条目。如果上一个条目和当前条目之间的差异超过一天,则表示缺少天数。

    有一种方法可以实现:

    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)运行。

        3
  •  2
  •   John La Rooy    16 年前
    >>> 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 datetime.datetime 物体

        4
  •  1
  •   Ignacio Vazquez-Abrams    16 年前

    把日期放在一个盒子里 set 然后使用 datetime.timedelta()

        5
  •  1
  •   C. Snoeij    7 年前

    您需要的导入:

    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))
    

    而不是检查日期 all_dates 通过使用范围为的for循环并将这些日期添加到缺少的日期:

    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

        6
  •  0
  •   jfs    16 年前
    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)]
    
        7
  •  0
  •   John La Rooy    16 年前

    使用列表理解

    >>> 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)]
    
        8
  •  0
  •   Bishwas Mishra    9 年前

    创建一个函数,为您提供从 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