web-dev-qa-db-fra.com

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

J'aimerais que ma sortie soit:

{1: 'one', 2: 'two'}

Pour clarifier, je voudrais que mon résultat soit l'équivalent de ce qui suit:

res = dict()
res[1] = 'one'
res[2] = 'two'

Une manière pythonienne soignée pour y parvenir?

Merci

80
Roee Adler

Python 2:

res = dict((v,k) for k,v in a.iteritems())

Python 3 (merci à @erik):

res = dict((v,k) for k,v in a.items())
130
liori
new_dict = dict (Zip(my_dict.values(),my_dict.keys()))
52
Javier

À 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'}
44
SilentGhost
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'}
30
sunqiang

Vous pouvez utiliser compréhensions dict :

res = {v: k for k, v in a.iteritems()}

Modifié: Pour Python 3, utilisez a.items() au lieu de a.iteritems(). Les discussions sur les différences entre elles peuvent être trouvées dans iteritems dans Python sur SO.

27
Akavall

Tu pourrais 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

  1. 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 touche 1.
  2. Une ou plusieurs des valeurs ne sont pas partageables. 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.

18
Alasdair
new_dict = dict( (my_dict[k], k) for k in my_dict)

ou encore mieux, mais ne fonctionne que dans Python 3:

new_dict = { my_dict[k]: k for k in my_dict}
14
balpha

res = dict(Zip(a.values(), a.keys()))

13
pkit

Une autre façon d'étendre la réponse de Ilya Prokin consiste à utiliser la fonction reversed.

dict(map(reversed, my_dict.items()))

En substance, votre dictionnaire est itéré via (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 transmis au constructeur dict, il les transforme en paires valeur/clé, ce que vous voulez.

10
Sunny Patel

La première réponse actuelle suppose que les valeurs sont uniques, ce qui n'est pas toujours le cas. Et 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()} 

résultats {2: 'b', 3: 'a'}.

Les informations sur 'c' a été complètement ignoré. Idéalement, cela devrait être quelque chose comme {2: ['b','c'], 3: ['a']}. C'est ce que fait la dernière implémentation.

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
10
Hanan Shteingart

Suggestion d'amélioration pour la réponse de Javier:

dict(Zip(d.values(),d))

Au lieu de d.keys(), vous pouvez écrire simplement d, car si vous parcourez le dictionnaire avec un itérateur, il renverra les clés du dictionnaire correspondant.

Ex. pour ce comportement:

d = {'a':1,'b':2}
for k in d:
 k
'a'
'b'
6
shadow2097
dict(map(lambda x: x[::-1], YourDict.items()))

.items() renvoie une liste de tuples de (key, value). map() parcourt les éléments de la liste et applique lambda x:[::-1] à chacun de ses éléments (Tuple) pour l'inverser, ainsi 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.

2
Ilya Prokin

Peut être fait facilement avec la compréhension du dictionnaire:

{d[i]:i for i in d}
2
user10084443

Ajout d'une solution sur place:

>>> 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 utilisiez list(d.keys()) car dict.keys Renvoie un affichage des clés. Si vous utilisez Python2, d.keys() suffit.

1
timgeb

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
1
Devesh Saini

Si vous utilisez Python3, c'est légèrement différent:

res = dict((v,k) for k,v in a.items())
1
Gravity Grave