2013-01-04 2 views
3

Позволяет иметь следующий Dict:ключей питона запроса в словаре на основе значений

table = {x1: {y1: 1, y2:2}, 
     x2: {y1: 3, y2:4}, 
     x3: {y3: 5, y2:6} 
     } 

Учитывая, что значения уникальны, есть ли способ запроса ключа пути эффективно на основе значения или лучше Восстановить dict, используя значение в качестве ключа?

Пример:

result = magic_function(table, 3) 
    result --> [x2, y1] 

Спасибо,

+0

является значение гарантированно быть уникальным во всем dict? –

+1

Я не знаю, что еще вы делаете с dict, поэтому одним из способов может быть использование значений использования в качестве ключей и наоборот. – ajmartin

+0

Да, они уникальны. – Amir

ответ

5

идиоматических способ "инвертировать" словарь как это:

i = {v: k for (k, v) in d.items()} 

Если вы в Python 2, а не 3, и d может быть большой, используйте вместо этого iteritems.

В вашем случае у вас есть dict из dicts, и вы хотите, чтобы я правильно разобрал его преобразование в dict путей. Но вы не знаете, как это написать. Итак, давайте начнем писать его в явном виде, длинный путь:

i = {} 
for k, v in d.items(): 
    for k2, v2 in v.items(): 
     i[v2] = (k, k2) 

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

2

Inverting, вероятно, лучший способ пойти:

In [17]: d = {table[k1][k2]: (k1,k2) for k1 in table for k2 in table[k1]} 

Вот решением обработки произвольной глубины и "рваную" dicts:

def invert_arbitrary(d, ldict, p=[]): 
    for k, v in ldict.items(): 
     if isinstance(v, dict): 
      invert_arbitrary(d, v, p + [k]) 
     else: 
      d[v] = p + [k] 

Пример:

table = {'x1': {'y1': 1, 'y2': 2}, 
     'x2': {'y1': 3, 
       'y2': {'z1': 4, 'z2': 5}}, 
     'x3': 6} 

In [40]: d = dict() 
In [41]: invert_arbitrary(d, table) 

In [42]: d 
Out[42]: 
{1: ['x1', 'y1'], 
2: ['x1', 'y2'], 
3: ['x2', 'y1'], 
4: ['x2', 'y2', 'z1'], 
5: ['x2', 'y2', 'z2'], 
6: ['x3']} 
+0

Почему вы используете 'dict' в выражении генератора вместо того, чтобы просто использовать понимание словаря? – abarnert

+0

@abarnert Спасибо, я просто пропустил это. Исправлено. –

+0

Спасибо abarnert, я очень ценю ваш комментарий. –

Смежные вопросы