Фильтровать диктат - PullRequest
3 голосов
/ 13 мая 2011

Я новичок в Python, и я не уверен, что это хорошая идея использовать dict of dict, но вот мой вопрос.У меня есть dict of dict, и я хочу отфильтровать по ключу внутреннего dict:

a ={ 'key1' : {'id1' :[0,1,2] , 'id2' :[0,1,2], 'id3' :[4,5,6]}
     'key2' : {'id3' :[0,1,2] , 'id4' :[0,1,2]}
     'key3' : {'id3' :[0,1,2] , 'id1' :[4,5,6]}
   }

Например, я хочу отфильтровать по 'id1', чтобы иметь:

result = { 'key1' : {'id1' :[0,1,2] }
           'key3' : {'id1' :[4,5,6]}
         }

Я пробовал метод фильтра, получая все значения:

r = [('key1' ,{'id1' :[0,1,2] , 'id2' :[0,1,2], 'id3' :[4,5,6]})
     ('key3' , {'id3' :[0,1,2] , 'id1' :[4,5,6]})
   ]

Кроме того, метод фильтра возвращает список, и я хочу сохранить формат в качестве диктанта.

Заранее спасибо

Ответы [ 4 ]

5 голосов
/ 13 мая 2011

Попробуйте это:

>>> { k: v['id1'] for k,v in a.items() if 'id1' in v }
{'key3': [4, 5, 6], 'key1': [0, 1, 2]}

Для Python 2.x вы можете предпочесть использовать iteritems() вместо items(), и вам все еще понадобится довольно свежий питон (думаю, 2.7) для словарного понимания: для старых питонов используйте:

dict((k, v['id1']) for k,v in a.iteritems() if 'id1' in v )

Если вы хотите извлечь несколько значений, тогда я думаю, что вам лучше всего написать циклы полностью:

def query(data, wanted):
    result = {}
    for k, v in data.items():
        v2 = { k2:v[k2] for k2 in wanted if k2 in v }
        if v2:
            result[k] = v2
    return result

дает:

>>> query(a, ('id1', 'id2'))
{'key3': {'id1': [4, 5, 6]}, 'key1': {'id2': [0, 1, 2], 'id1': [0, 1, 2]}}
2 голосов
/ 13 мая 2011

В соответствии с точностью, которую вы дали Дункану, вот еще одна фильтрация списка с использованием словарного понимания:

>>> my_list = ['id1', 'id2']
>>> {k1 : {k2: v2 for (k2, v2) in a[k1].iteritems() if k2 in my_list} for k1 in a}
{'key3': {'id1': [4, 5, 6]}, 'key2': {}, 'key1': {'id2': [0, 1, 2], 'id1': [0, 1, 2]}}

РЕДАКТИРОВАТЬ: вы также можете удалить пустые значения с помощью другой диктовки, но это "начинается"быть трудно читать ...: -)

>>> {k3: v3 for k3, v3 in {k1 : {k2: v2 for (k2, v2) in a[k1].iteritems() if k2 in my_list} for k1 in a}.iteritems() if v3}
{'key3': {'id1': [4, 5, 6]}, 'key1': {'id2': [0, 1, 2], 'id1': [0, 1, 2]}}
1 голос
/ 13 мая 2011
field = 'id1'
dict( (k,{field: d[field]}) for k,d in a.items() if field in d)
1 голос
/ 13 мая 2011

Вы можете сделать с пониманием словаря:

def query(data, query):
    return {key : {query : data[key][query]} 
            for key in data if query in data[key]}

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

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