Как эффективно извлечь списки значений из словаря при поиске по этим значениям в Python? - PullRequest
0 голосов
/ 14 июня 2019

У меня есть большой файл журнала, который после разбора в словарь принимает вид:

data = {id: {"datetime": datetime, "string": string}}

где:

datetime: str
string: str
id: int    

(диктат с вложенными диктовками) например:

data = {
0: {"datetime": "03.04.2019", "string":"abc"},
1: {"datetime": "04.04.2019", "string":"abc"},
2: {"datetime": "05.04.2019", "string":"abc"},
3: {"datetime": "05.04.2019", "string":"xyz"},
4: {"datetime": "06.04.2019", "string":"abc"},
5: {"datetime": "06.04.2019", "string":"xyz"},
6: {"datetime": "07.04.2019", "string":"abc"}
}

Как видите, ни дата, ни строка не являются уникальными в каждом из вложенных словарей. Однако с каждым последующим идентификатором следующие datetime больше или равны предыдущим datetime.

Я хочу создать функцию, которая извлекает только внутренние диктанты между конкретными датами и включительно. Например, моя функция:

def extract(start_datetime, end_datetime, data)
    ...

для параметров:

extract("05.04.2019", "06.04.2019", data)

должен вернуть:

{
2: {"datetime": "05.04.2019", "string":"abc"},
3: {"datetime": "05.04.2019", "string":"xyz"},
4: {"datetime": "06.04.2019", "string":"abc"},
5: {"datetime": "06.04.2019", "string":"xyz"}
}

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

Ответы [ 2 ]

0 голосов
/ 14 июня 2019

сорт одного вкладыша

import time

data = {
    0: {"datetime": "03.04.2019", "string": "abc"},
    1: {"datetime": "04.04.2019", "string": "abc"},
    2: {"datetime": "05.04.2019", "string": "abc"},
    3: {"datetime": "05.04.2019", "string": "xyz"},
    4: {"datetime": "06.04.2019", "string": "abc"},
    5: {"datetime": "06.04.2019", "string": "xyz"},
    6: {"datetime": "07.04.2019", "string": "abc"}
}

data_in_time_range = [entry for entry in data.values() if
                      time.strftime(entry['datetime']) >= time.strftime('05.04.2019') and time.strftime(
                          entry['datetime']) <= time.strftime('06.04.2019')]
print(data_in_time_range) 

выход:

[{'datetime': '05.04.2019', 'string': 'abc'}, {'datetime': '05.04.2019', 'string': 'xyz'}, {'datetime': '06.04.2019', 'string': 'abc'}, {'datetime': '06.04.2019', 'string': 'xyz'}]
0 голосов
/ 14 июня 2019

Другая возможность будет:

import time

def extract(start, end, data): 
    output_dict= {}
    for key, val in data.items(): 
        if (isinstance(val, dict) 
            and time.strftime(val.get('datetime')) >= time.strftime(start) 
            and time.strftime(val.get('datetime')) <= time.strftime(end)): 
            output_dict[key] = val
    return output_dict

extract("05.04.2019", "06.04.2019", data)  

Выход:

{2: {'datetime': '05.04.2019', 'string': 'abc'},
 3: {'datetime': '05.04.2019', 'string': 'xyz'},
 4: {'datetime': '06.04.2019', 'string': 'abc'},
 5: {'datetime': '06.04.2019', 'string': 'xyz'}}

...