claves de consulta de Python en un diccionario basado en valores

Vamos a tener un dictado siguiente:

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

Teniendo en cuenta que los valores son únicos, ¿hay alguna forma de consultar la ruta de la clave en función del valor de manera eficiente o es mejor reconstruir el dict utilizando el valor como la clave?

Ejemplo:

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

Gracias,

La forma idiomática de “invertir” un diccionario es así:

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

Si estás en Python 2 en lugar de 3, y d podría ser grande, usa iteritems en iteritems lugar.

En su caso, tiene un dicts de dicts , y quiere una especie de doble inversión en un dict de caminos, si lo entiendo correctamente. Pero no sabes cómo escribir eso. Entonces, comencemos por escribirlo explícitamente, el camino largo:

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

Puedes convertir esto en un diccionario de comprensión, pero quieres que sea algo que realmente entiendas, en lugar de una invocación mágica que puedes copiar y pegar sin pensar, así que dejaré esa parte en tus manos (pero estaré encantado de hacerlo). ayuda si tiene alguna pregunta).

Invertir es probablemente la mejor manera de ir:

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

Aquí hay una solución que maneja profundidad arbitraria y dictados “desiguales”:

 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] 

Ejemplo:

 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']}