2013-06-09 4 views
1

У меня есть список datetime.dates, и мне нужно проверить, будет ли каждая дата со следующего месяца подряд.Определение последовательных дат

Надеется, что это понятно, что я имею в виду из кода:

import datetime 
from unittest import TestCase 


def is_consecutive(dates): 
    # TODO 
    return 


class DatesTestCase(TestCase): 
    def test_consecutive(self): 
     self.assertTrue(is_consecutive([datetime.date(2010, 10, 3), 
             datetime.date(2010, 11, 8), 
             datetime.date(2010, 12, 1), 
             datetime.date(2011, 01, 11)])) 

    def test_not_consecutive(self): 
     self.assertFalse(is_consecutive([datetime.date(2010, 7, 6), 
             datetime.date(2010, 8, 24), 
             datetime.date(2010, 3, 5), 
             datetime.date(2010, 10, 25)])) 

     self.assertFalse(is_consecutive([datetime.date(2010, 10, 6), 
             datetime.date(2010, 11, 2), 
             datetime.date(2010, 12, 9), 
             datetime.date(2010, 01, 20)])) 

Как бы реализовать is_consecutive?

Большое спасибо за помощь (совет, подсказка, код или что-нибудь полезное)!

ответ

2

Прокрутите каждый элемент списка, за исключением последнего, и сравните его со следующим элементом. Два элемента являются последовательными, если месяц второго - ровно один больше, чем месяц первого, или если месяц второго равен 1, а год второго - ровно на один больше, чем год первого. Возврат False при первом сбое, в противном случае возврат True в конце.

EDIT: во втором случае, очевидно, месяц первого должен быть 12, в дополнение к месяцу второго - 1. Код обновлен.

EDIT 2: И в первом случае, очевидно, год должен быть таким же. Это то, что вы получаете для написания слишком быстро.

F'rinstance:

#!/usr/bin/python 

from datetime import date 

def is_consecutive(datelist): 
    for idx, my_date in enumerate(datelist[:-1]): 
     if ((datelist[idx + 1].month - my_date.month == 1 and 
      datelist[idx + 1].year == my_date.year) or 
      (datelist[idx + 1].month == 1 and 
      my_date.month == 12 and 
      datelist[idx + 1].year - my_date.year == 1)): 
      continue 
     else: 
      return False 
    return True 

print is_consecutive([date(2010, 10, 3), 
         date(2010, 11, 8), 
         date(2010, 12, 1), 
         date(2011, 1, 11)]) 

print is_consecutive([date(2010, 7, 6), 
         date(2010, 8, 24), 
         date(2010, 3, 5), 
         date(2010, 10, 25)]) 

Альтернативная реализация, возможно, легче следовать, но в основном делает то же самое:

def is_consecutive(datelist): 
    for idx, my_date in enumerate(datelist[:-1]): 
     month_diff = datelist[idx + 1].month - my_date.month 
     year_diff = datelist[idx + 1].year - my_date.year 
     if ((month_diff == 1 and year_diff == 0) or 
      (month_diff == -11 and year_diff == 1)): 
      continue 
     else: 
      return False 
    return True 
2

Это работает на ваших примерах и должен работать, как правило:

def is_consecutive(data): 
    dates=data[:] 
    while len(dates)>1: 
     d2=dates.pop().replace(day=1) 
     d1=dates[-1].replace(day=1) 
     d3=d1+datetime.timedelta(days=32) 
     if d3.month!=d2.month or d3.year!=d2.year: 
      return False   
    return True 
+0

Это, кажется, ложно возвращает True для списка, такого как [date (2010,9,3), date (2010, 10, 8), date (2010, 12, 1), date (2011, 1, 11)], где вторая и третья даты не являются последовательными. Я думаю, вы, вероятно, должны были бы вернуть одну из этих дат в список, иначе вы будете сопоставлять пары дат, но не каждая из них будет последовательной со следующей. –

+0

@PaulGriffiths: Да, вы правы. Я принимал данные по-разному, а не поочередно. Исправлена – dawg

1

Вот еще одно решение этой проблемы:

def is_consecutive(dates): 
    months = [date.month for date in sorted(dates)] # extracting months from date, dates list has to be sorted first 
    months_diff = [abs(x - months[i - 1]) for i, x in enumerate(months) if i>0] # creates a resulting list of values after subtracting month with a previous month (absolute value is needed to account for the case when subtracting December(12) from January(1) 
    if not(set(months_diff) - set([1,11])): # if months_diff contains any values other than 11 and 1 then dates are not consecutive 
     return True 
    return False 
Смежные вопросы