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

58
demandé sur Roee Adler 2009-06-23 14:53:12

16 réponses

res = dict((v,k) for k,v in a.iteritems())
91
répondu liori 2009-06-23 11:00:16
new_dict = dict (zip(my_dict.values(),my_dict.keys()))
49
répondu Javier 2009-07-06 16:09:46

À 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'}
41
répondu SilentGhost 2013-02-25 20:08:27
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'}
31
répondu sunqiang 2009-07-06 15:43:30

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.

25
répondu Akavall 2018-02-03 16:35:56

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

  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 clé 1.
  2. 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.

18
répondu Alasdair 2009-12-02 02:28:02
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}
14
répondu balpha 2009-07-06 15:46:48

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

11
répondu pkit 2009-06-23 10:55:34

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.

8
répondu Sunny Patel 2017-05-23 12:10:10

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
5
répondu Hanan Shteingart 2017-08-03 23:20:15

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'
4
répondu shadow2097 2011-07-28 22:27:44

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
répondu Devesh Saini 2014-08-09 14:29:03

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

res = dict((v,k) for k,v in a.items())
1
répondu Gravity Grave 2014-08-09 17:42:46
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.

1
répondu Ilya Prokin 2015-09-10 19:48:38

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.

1
répondu timgeb 2016-04-15 07:17:01

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

{d[i]:i for i in d}
1
répondu user10084443 2018-07-15 14:53:11