получить значение dict по части ключевого питона - PullRequest
0 голосов
/ 08 ноября 2018

Я хочу получить значение из словаря по части ключа, например, У меня есть dict с составным ключом

tr_dict = {'UTABI-OSGAN': {"properties": {"id": "789"}},
       'ABOKA-OSGAN': {"properties": {"id": "111"}},
       'FE-DERIG': {"properties": {"id": "243"}}}

и я хочу получить значения при запущенном ключе 'UTABI' (другой случай, когда ключ заканчивается, например, 'DERIG')

Полагаю, это выглядит как

start = 'UTABI' 
tr_dict.get(start + '[-A-Z]{2,5}')

Я знаю, что этот синтаксис неправильный, но возможно ли сделать что-то подобное?

Ответы [ 3 ]

0 голосов
/ 08 ноября 2018

Синтаксис, который вы предлагаете, интерпретируется как "дайте мне" UTABI [-AZ] {2,5} "ключ".

Поскольку вы хотите фильтровать "по намерению", вы можете сказать:

filtered_dict = {key: value for key, value in tr_dict if key.startswith('UTABI')}
0 голосов
/ 08 ноября 2018

Краткий ответ: нет. Dicts не являются базами данных SQL, вы должны дать точный ключ.

Решение для грубой силы состоит в том, чтобы перебрать ключи dict и использовать строковые методы, чтобы найти соответствующие, то есть:

for key in tr_dict:
    if key.startswith("UTABI-"):
        print("found {} : {}".format(key, tr_dict[key]))

что, конечно, является O (n) и отчасти побеждает весь смысл наличия диктов. Это нормально, если вам нужно выполнить этот поиск только один раз для данного tr_dict, но неоптимально, если tr_dict имеет длительный срок службы и будет найден несколько раз для данного "частичного" ключа.

Другое решение, которое требует дополнительной предварительной обработки, но допускает последующий доступ O (1), состоит в том, чтобы предварительно обработать весь dict один раз, чтобы создать новый с ключами, которые можно искать напрямую:

from collections import defaultdict

lookups = [
   # (key: callback)
   ("UTABI", lambda k: k.startswith("UTABI-")),
   ("DERIG", lambda k: k.endswith("-DERIG")),
   ]

index = defaultdict(list)
for newkey, match in lookups:
    for oldkey in tr_dict:
        if match(oldkey):
            index[newkey].append(tr_dict[oldkey])

Это перебор для одноразового поиска, но гораздо лучше, если вам приходится искать эти ключи более одного раза для данного tr_dict.

0 голосов
/ 08 ноября 2018

Вот один из способов сделать это,

return_values = {k:v for k,v in tr_dict.items() if k.startswith('UTABI') or k.endswith('DERIG')}
print(return_values)

Выходы:

{'UTABI-OSGAN': {'properties': {'id': '789'}}, 'FE-DERIG': {'properties': {'id': '243'}}}

А вот расширенная форма, которая делает то же самое

return_values = []
for k,v in tr_dict.items():
    if k.startswith('UTABI') or k.endswith('DERIG'): # Change your requirements here
        return_values.append(v)

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