Python: La meilleure façon d'échanger des clés avec des valeurs dans un dictionnaire?
Je reçois un dictionnaire en entrée, et je voudrais retourner un dictionnaire dont les clés seront les valeurs de l'entrée et dont la valeur sera les clés d'entrée correspondantes. Les valeurs sont uniques.
Par exemple, disons que mon entrée est:
a = dict()
a['one']=1
a['two']=2
Je voudrais que ma sortie soit:
{1: 'one', 2: 'two'}
Pour clarifier, je voudrais que mon résultat soit l'équivalent de la suivante:
res = dict()
res[1] = 'one'
res[2] = 'two'
Une façon pythonienne soignée d'y parvenir?
Merci
16 réponses
À partir de python 2.7, y compris 3.0+, il existe une version sans doute plus courte et plus lisible:
>>> my_dict = {'x':1, 'y':2, 'z':3}
>>> {v: k for k, v in my_dict.items()}
{1: 'x', 2: 'y', 3: 'z'}
In [1]: my_dict = {'x':1, 'y':2, 'z':3}
In [2]: dict((value, key) for key, value in my_dict.iteritems())
Out[2]: {1: 'x', 2: 'y', 3: 'z'}
Vous pouvez utiliser dict compréhensions :
res = {v: k for k, v in a.iteritems()}
Édité: pour Python 3, Utilisez a.items()
au lieu de a.iteritems()
. Les Discussions sur les différences entre eux peuvent être trouvées dans iteritems dans Python sur SO.
Vous pouvez essayer:
d={'one':1,'two':2}
d2=dict((value,key) for key,value in d.iteritems())
d2
{'two': 2, 'one': 1}
Attention, vous ne pouvez pas 'inverser' un dictionnaire si
- plusieurs clés partagent la même valeur. Par exemple
{'one':1,'two':1}
. Le nouveau dictionnaire ne peut avoir qu'un seul élément avec la clé1
. - une ou plusieurs des valeurs ne sont pas hachables. Par exemple
{'one':[1]}
.[1]
est une valeur valide, mais pas une clé valide.
Voir ce fil sur la liste de diffusion python pour une discussion sur le sujet.
new_dict = dict( (my_dict[k], k) for k in my_dict)
Ou encore mieux, mais ne fonctionne qu'en Python 3:
new_dict = { my_dict[k]: k for k in my_dict}
Une autre façon de développer la réponse de Ilya Prokin est d'utiliser la fonction reversed
.
dict(map(reversed, my_dict.items()))
En substance, votre dictionnaire est itéré (en utilisant .items()
) où chaque élément est une paire clé / valeur, et ces éléments sont échangés avec la fonction reversed
. Lorsque cela est passé au constructeur dict
, il les transforme en paires valeur/clé, ce que vous voulez.
La réponse principale actuelle suppose que les valeurs sont uniques, ce qui n'est pas toujours le cas. Si les valeurs ne sont pas uniques? Vous perdrez des informations! Par exemple:
d = {'a':3, 'b': 2, 'c': 2}
{v:k for k,v in d.iteritems()}
Renvoie {2: 'b', 3: 'a'}
.
Les informations sur 'c'
ont été complètement ignorées.
Idéalement, il devrait avoir quelque chose comme {2: ['b','c'], 3: ['a']}
. C'est ce que fait l'implémentation du bas.
def reverse_non_unique_mapping(d):
dinv = {}
for k, v in d.iteritems():
if v in dinv:
dinv[v].append(k)
else:
dinv[v] = [k]
return dinv
Suggestion pour une amélioration pour Javier réponse:
dict(zip(d.values(),d))
Au lieu de d.keys()
Vous pouvez écrire juste d
, parce que si vous passez par dictionnaire avec un itérateur, il retournera les clés du dictionnaire pertinent.
Ex. pour ce comportement:
d = {'a':1,'b':2}
for k in d:
k
'a'
'b'
En utilisant boucle:-
newdict = {} #Will contain reversed key:value pairs.
for key, value in zip(my_dict.keys(), my_dict.values()):
# Operations on key/value can also be performed.
newdict[value] = key
Si vous utilisez Python3, c'est légèrement différent:
res = dict((v,k) for k,v in a.items())
dict(map(lambda x: x[::-1], YourDict.items()))
.items()
retourne une liste de tuples de (key, value)
. {[3] } parcourt les éléments de la liste et applique lambda x:[::-1]
à chaque élément (tuple) pour l'Inverser, de sorte que chaque tuple devient (value, key)
dans la nouvelle liste crachée hors de la carte. Enfin, dict()
fait un dict à partir de la nouvelle liste.
Ajout d'une solution:
>>> d = {1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> for k in list(d.keys()):
... d[d.pop(k)] = k
...
>>> d
{'two': 2, 'one': 1, 'four': 4, 'three': 3}
En Python3, il est essentiel que vous utilisez list(d.keys())
, car dict.keys
retourne un afficher des clés. Si vous utilisez Python2, d.keys()
est suffisant.
Peut être fait facilement avec la compréhension du dictionnaire:
{d[i]:i for i in d}