Dado un diccionario como este:
my_map = {'a': 1, 'b': 2}
¿Cómo se puede invertir este mapa para obtener:
inv_map = {1: 'a', 2: 'b'}
python
dictionary
mapping
reverse
Brian M. Hunt
fuente
fuente
my_map.items()
funcionaThe order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon
. No hay garantía de que se mantenga así, así que no escriba código confiando enDict
tener el mismo comportamiento queOrderedDict
.Suponiendo que los valores en el dict son únicos:
fuente
iteritems()
saldrá, por lo que se puede suponer que se asignará una clave arbitraria para un valor no único, de una manera que aparentemente será reproducible en algunas condiciones, pero en general no.iteritems()
método y este enfoque no funcionará; use enitems()
su lugar como se muestra en la respuesta aceptada. Además, una comprensión del diccionario lo haría más bonito que llamardict
.Si los valores en
my_map
no son únicos:fuente
inv_map.get(v, [])
devuelve la lista ya agregada si hay una, por lo que la asignación no se restablece a una lista vacía.setdefault
sin embargo, aún sería más bonita.inv_map.setdefault(v, set()).add(k)
.my_map.items()
lugar demy_map.iteritems()
.Para hacer esto mientras se preserva el tipo de su mapeo (suponiendo que sea una
dict
o unadict
subclase):fuente
Prueba esto:
(Tenga en cuenta que los documentos de Python en las vistas de diccionario garantizan explícitamente que
.keys()
y.values()
tienen sus elementos en el mismo orden, lo que permite que funcione el enfoque anterior).Alternativamente:
o usando las comprensiones dict de python 3.0
fuente
Otra forma más funcional:
fuente
filter
ymap
debería morir y ser incluido en las comprensiones de la lista, no crecer más variantes".dict
con otros tipos de mapeo comocollections.OrderedDict
ocollections.defaultdict
Esto amplía la respuesta de Robert , aplicando cuando los valores en el dict no son únicos.
La implementación es limitada, ya que no se puede usar
reversed
dos veces y recuperar el original. No es simétrico como tal. Se prueba con Python 2.6. Aquí hay un caso de uso de cómo estoy usando para imprimir el dict resultante.Si prefiere usar a
set
que alist
, y podría existir aplicaciones desordenadas para las que esto tiene sentido, en lugar desetdefault(v, []).append(k)
usarsetdefault(v, set()).add(k)
.fuente
revdict.setdefault(v, set()).add(k)
set
. Es el tipo intrínseco que se aplica aquí. ¿Qué sucede si quiero encontrar todas las claves donde los valores no son1
o2
? Entonces solo puedo hacerd.keys() - inv_d[1] - inv_d[2]
(en Python 3)También podemos revertir un diccionario con claves duplicadas usando
defaultdict
:Mira aquí :
fuente
Por ejemplo, tiene el siguiente diccionario:
Y quieres obtenerlo en una forma tan invertida:
La primera solución . Para invertir pares clave-valor en su diccionario, utilice un
for
enfoque de bucle:Segunda solución . Utilice un enfoque de comprensión del diccionario para la inversión:
Tercera solución . Utilice revertir el enfoque de inversión (se basa en la segunda solución):
fuente
dict
está reservado y no debe usarse para nombres de variablesmy_map
esdictio()
? Quiso decirdict()
?Combinación de lista y comprensión de diccionario. Puede manejar claves duplicadas
fuente
Si los valores no son únicos y eres un poco duro:
Especialmente para un dict grande, tenga en cuenta que esta solución es mucho menos eficiente que la respuesta Python invertir / invertir una asignación porque se repite
items()
varias veces.fuente
-1
porque todavía responde la pregunta, solo mi opinión.Además de las otras funciones sugeridas anteriormente, si le gustan las lambdas:
O también puedes hacerlo de esta manera:
fuente
Creo que la mejor manera de hacer esto es definir una clase. Aquí hay una implementación de un "diccionario simétrico":
Los métodos de eliminación e iteración son lo suficientemente fáciles de implementar si son necesarios.
Esta implementación es mucho más eficiente que invertir un diccionario completo (que parece ser la solución más popular en esta página). Sin mencionar que puede agregar o eliminar valores de su SymDict tanto como desee, y su diccionario inverso siempre será válido; esto no es cierto si simplemente invierte todo el diccionario una vez.
fuente
dictresize
, pero este enfoque niega a Python esa posibilidad.Esto maneja valores no únicos y conserva gran parte del aspecto del caso único.
Para Python 3.x, reemplace
itervalues
convalues
.fuente
La función es simétrica para los valores de la lista de tipos; Las tuplas se convierten en listas cuando se realiza reverse_dict (reverse_dict (diccionario))
fuente
Dado que los diccionarios requieren una clave única dentro del diccionario a diferencia de los valores, tenemos que agregar los valores invertidos en una lista de clasificación para incluirlos en las nuevas claves específicas.
fuente
Solución funcional rápida para mapas no biyectivos (valores no únicos):
En teoría, esto debería ser más rápido que agregar al conjunto (o agregar a la lista) uno por uno, como en la solución imperativa .
Desafortunadamente, los valores tienen que ser ordenables, la clasificación es requerida por groupby
fuente
n
elementos en el dict original, su enfoque tieneO(n log n)
complejidad de tiempo debido a la necesidad de clasificar los elementos del dict, mientras que el enfoque imperativo ingenuo tieneO(n)
complejidad de tiempo. Por lo que sé, su enfoque puede ser más rápido hasta absurdamente grandedict
en la práctica , pero ciertamente no es más rápido en teoría.Prueba esto para python 2.7 / 3.x
fuente
Lo haría de esa manera en Python 2.
fuente
dict.items
(oiteritems
en Python 2) es más eficiente que extraer cada valor por separado mientras se repiten las claves.Esto proporcionará resultados como: {1: ['a', 'd'], 2: ['b'], 3: ['c']}
fuente
dict.items
(oiteritems
en Python 2) es más eficiente que extraer cada valor por separado mientras se repiten las claves. Además, no ha agregado ninguna explicación a una respuesta que duplica a otras.este código hace así:
fuente
No es algo completamente diferente, solo una receta un poco reescrita de Cookbook. Además, está optimizado por el
setdefault
método de retención , en lugar de hacerlo cada vez a través de la instancia:Diseñado para ejecutarse en CPython 3.x, para 2.x reemplazar
mapping.items()
conmapping.iteritems()
En mi máquina funciona un poco más rápido que otros ejemplos aquí
fuente
dict
ay luego convertirlo a la clase deseada al final (en lugar de comenzar con una clase del tipo correcto) me parece que incurre en un éxito de rendimiento completamente evitable, aquí.Escribí esto con la ayuda del ciclo 'for' y el método '.get ()' y cambié el nombre 'map' del diccionario a 'map1' porque 'map' es una función.
fuente
Si los valores no son únicos Y pueden ser un hash (una dimensión):
Y con una recursión si necesita profundizar, solo una dimensión:
fuente
{"foo": "bar"}
a{'b': ['foo'], 'a': ['foo'], 'r': ['foo']}
y levanta una excepción si cualquier valor enmyDict
no es un iterable. No estoy seguro de qué comportamiento estaba tratando de implementar aquí, pero lo que realmente ha implementado es algo que nadie querrá.