Как эффективно сравнить объект datetime - PullRequest
0 голосов
/ 12 октября 2018

У меня есть словарь с примерно 15k записями, который отформатирован так:

sample = {0: {'Schedule': ['2017-05-11', '2019-04-30', '2018-10-13', '2019-05-31', '', '']},
      1: {'Schedule': ['2017-05-09', '2019-05-31', '', '', '2018-10-13', '2019-05-31']},
      2: {'Schedule': ['2017-05-02', '2020-02-29', '', '', '2018-10-12', '2020-02-29']}}

Теперь мне нужно сравнить 1-ю, 3-ю и 5-ю даты в 'Schedule' с двумя объектами datetime и посмотреть, падает лив пределах диапазона.Я делаю ниже, но результат довольно медленный и занимает около 20 секунд.Кто-нибудь может предложить более эффективный способ поиска?

Полный пример кода:

from datetime import datetime

sample = {0: {'Schedule': ['2017-05-11', '2019-04-30', '2018-10-13', '2019-05-31', '', '']},
          1: {'Schedule': ['2017-05-09', '2019-05-31', '', '', '2018-10-13', '2019-05-31']},
          2: {'Schedule': ['2017-05-02', '2020-02-29', '', '', '2018-10-12', '2020-02-29']}}

start_date = datetime.date(datetime.strptime("2018-10-12","%Y-%m-%d"))
end_date = datetime.date(datetime.strptime("2018-10-16","%Y-%m-%d"))

for k,v in sample.items():
    earliest = [dt for dt in [v["Schedule"][0],v["Schedule"][2],v["Schedule"][4]] if dt] #only need to check these 3 starting dates
    def check_earliest(_list):  #check if any date meets search criteria
        for i in _list:
            if start_date <= datetime.date(datetime.strptime(i, "%Y-%m-%d")) <= end_date:
                return True
    if check_earliest(earliest):
        print ("Do something here...")

1 Ответ

0 голосов
/ 12 октября 2018

Не используйте объекты даты и времени, или начинаются с datetime объектов в вашем словаре, поэтому вам не нужно преобразовывать их только для этого сравнения.

Вы не делаетедолжны использовать datetime объекты, потому что ваши даты в порядке ГГГГ-ММ-ДД, определение ISO 8601 .Такие даты, как строки, лексикографически сопоставимы в правильном порядке для дат.

Так что

start_date = "2018-10-12"
end_date = "2018-10-16"

for k,v in sample.items():
    sched = v['Schedule']
    earliest = [dt for dt in (sched[0], sched[2], sched[4]) if dt]
    def check_earliest(l):
        for i in l:
            if start_date <= i <= end_date:
                return True
    if check_earliest(earliest):
        print("Do something here...")

уже работает отлично.

IДля проверки дат используйте здесь функцию any(), а не определяйте свою собственную функцию:

for k, v in sample.items():
    sched = v['Schedule']
    if any(sched[i] and start_date <= sched[i] <= end_date for i in (0, 2, 4)):
        print ("Do something here...")

Для других областей вашего кода может быть полезно проанализировать ваши строки в date() экземплярах один раз , а не использовать строки и конвертировать их каждый раз, когда вам нужен datetime.date() объект.Для только это сравнение здесь , это на самом деле не нужно.

...