Возврат нескольких значений из Python Dict с диапазоном даты и времени - PullRequest
0 голосов
/ 25 сентября 2018

У меня проблема с использованием DateTime в качестве ключа.Моя цель состоит в том, чтобы получить информацию из одного источника данных, который включает Datetime, а затем найти в словаре и вернуть все значения для ключей, которые находятся в пределах 2 дней + - от ввода DateTime.

Например, мойвходные данные будут: datetime.datetime(2018, 9, 20, 12, 48)

Мой словарь для справки будет: example = {datetime.datetime(2018, 9, 20, 14, 43):'A', datetime.datetime(2018, 9, 18, 19, 41):'B', datetime.datetime(2018, 9, 15, 9, 12):'C'}

В этом случае я бы вернул: A, B

Я рассмотрел сортировкусловарь и затем создание словаря индексов, возможно, для нечетных дат, затем взятие моей входной даты, вычисление базовой даты + - 2 входной даты, обращение к индексу dict, а затем использование этих индексов для циклического прохождения по ссылкедиктовать только между индексами и возвращать все значения, которые там есть.

Моя главная проблема в том, что я не могу предсказать, какой будет дата-время dict или входные даты-время, поэтому я просто не уверен, смогу ли я вернутьзначения для диапазона ключей в поле dict, кроме циклического перебора индекса ключей в отсортированном порядке.Выполнение цикла for для всех ключей здесь неэффективно из-за количества просматриваемых ключей - я уже сокращаю этот список, максимально сокращая дедупликацию и внося только минимальный объем справочных данных.

Еще один момент заключается в том, что мои входные данные будут искать 100 000 секунд, многие из которых будут находиться в минутах, секундах или часах друг от друга, поэтому сокращение числа поисков и циклов будетважно сохранить время выполнения.

Я прошу прощения, если это не совсем правильный вопрос с полным кодом, чтобы посмотреть, но я в основном не уверен, с чего начать по этому вопросу, поэтому я не думал, что этопомог бы кому-нибудь добавить что-нибудь еще, кроме ввода и словаря с целью вывода.

1 Ответ

0 голосов
/ 25 сентября 2018
  • Сначала отсортируйте словарные даты и преобразуйте словарь в список отсортированных кортежей:

    dic_dates = {
        datetime.datetime(2018, 9, 20, 14, 43):'A',
        datetime.datetime(2018, 9, 18, 12, 41):'B',
        datetime.datetime(2018, 9, 15, 9, 12):'C'
    }
    
    sorted_dates = sorted(dic_dates.items())
    
  • Затем используйте bisect, чтобы найти положение вашей датывнутри этого списка:

    dat = datetime.datetime(2018, 9, 20, 12, 48)
    insert_index = bisect.bisect_left(sorted_dates, (dat,None))
    
  • Посмотрите из этой позиции влево и сломайте, как только элемент не проверит условие, затем сделайте то же самое, начиная с позиции справа,(Вы можете использовать свои собственные условия, поскольку я обнаружил, что это было довольно неясно в вашем примере - + -2days не должны выбирать ИМ 'B', но это не главное)

    if insert_index:
    #if insert_index = 0, do not loop on left side
        dat_min = dat - datetime.timedelta(days=2)
        for d in sorted_dates[insert_index-1::-1]:
            if d[0] > dat_min:
                print(d[1])
            else:
                break
    
    dat_max = dat + datetime.timedelta(days=2)
    for d in sorted_dates[insert_index:]:
        if d[0] < dat_max:
            print(d[1])
        else:
            break
    

РЕДАКТИРОВАТЬ

Один из примеров реализации bisct_left:

def bisect_left(l, e, start = 0):
    if not l:
        return start
    pos = int(len(l)/2)
    if l[pos] < e and (pos+1 >= len(l) or l[pos+1] > e):
        return start + pos + 1
    elif l[pos] >= e:
        return bisect_left(l[:pos], e, start)
    else:
        return bisect_left(l[pos:], e, start+pos)

Я настоятельно советую вам использовать bisect, так как он будет быстрее и надежнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...