Python invierte / invierte una asignación (pero con múltiples valores para cada clave)

Esto es realmente una variación de esta pregunta, pero no un duplicado:

Python invierte / invierte un mapeo

Dado un diccionario como este:

mydict= { 'a': ['b', 'c'], 'd': ['e', 'f'] }

¿Cómo se puede invertir este dictado para obtener:

    inv_mydict = { 'b':'a', 'c':'a', 'e':'d', 'f':'d' }

    Tenga en cuenta que los valores se extienden de forma única en cada clave.

    Nota : anteriormente tenía el map = ... syntax map = ... y dict = ... Recordatorio de no usar map y dict ya que son funciones integradas, vea comentarios y respuestas excelentes a continuación 🙂

    TL; DR

    Usa la comprensión del diccionario, como esta

     >>> my_map = { 'a': ['b', 'c'], 'd': ['e', 'f'] } >>> {value: key for key in my_map for value in my_map[key]} {'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'} 

    La comprensión del diccionario visto anteriormente es funcionalmente equivalente a la siguiente estructura de bucle que llena un diccionario vacío

     >>> inv_map = {} >>> for key in my_map: ... for value in my_map[key]: ... inv_map[value] = key ... >>> inv_map {'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'} 

    Nota: Usando el map sombrea la función de map incorporada. Entonces, no uses eso como un nombre de variable a menos que sepas lo que estás haciendo.


    Otras formas similares de hacer lo mismo.

    Python 3.x

    Puedes usar dict.items , como este

     >>> {value: key for key, values in my_map.items() for value in values} {'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'} 

    Aquí usamos el método items() , que crearía un objeto de vista desde el diccionario que daría pares de valores clave en la iteración. Así que simplemente iteramos sobre él y construimos un nuevo diccionario con el mapeo inverso.

    Python 2.x

    Puedes usar dict.iteritems como este

     >>> {value: key for key, values in my_map.iteritems() for value in values} {'c': 'a', 'b': 'a', 'e': 'd', 'f': 'd'} 

    No preferimos el método items() en 2.x, porque devolverá una lista de pares clave-valor. No queremos construir una lista solo para iterar y construir un nuevo diccionario. Es por eso que preferimos iteritems() , que devuelve un objeto iterador que proporciona un par de valores clave en la iteración.

    Nota: el equivalente real de los items de Python 3.x sería el método viewitems Python 2.x, que devuelve un objeto de vista. Lea más sobre el objeto de vista en la documentación oficial, aquí .


    Métodos iter* vs view* en Python 2.x

    La principal diferencia entre las funciones iter* y las funciones view* en Python 2.x es que los objetos de la vista reflejan el estado actual del diccionario. Por ejemplo,

     >>> d = {1: 2} >>> iter_items = d.iteritems() >>> view_items = d.viewitems() 

    Ahora agregamos un nuevo elemento al diccionario.

     >>> d[2] = 3 

    Si intenta verificar si (2, 3) (par clave-valor) está en iter_items , se generará un error.

     >>> (2, 3) in iter_items Traceback (most recent call last): File "", line 1, in  RuntimeError: dictionary changed size during iteration 

    pero el objeto de vista reflejará el estado actual del diccionario. Por lo tanto, funcionará bien

     >>> (2, 3) in view_items True 
     mp = { 'a': ['b', 'c'], 'd': ['e', 'f'] } pm={} for x in mp.iterkeys(): for d in mp[x]: pm[d]=x print pm 

    Salida:

    {‘c’: ‘a’, ‘b’: ‘a’, ‘e’: ‘d’, ‘f’: ‘d’}

    Nota: un diccionario es una estructura de datos no ordenada, por lo que el resultado no se puede ordenar como desea.