web-dev-qa-db-fra.com

Comment puis-je trier un dictionnaire par clé?

Quelle serait une bonne façon de passer de {2:3, 1:89, 4:5, 3:0} à {1:89, 2:3, 3:0, 4:5}?
J'ai vérifié certains messages, mais ils utilisent tous l'opérateur "trié" qui renvoie les tuples. 

714
achrysochoou

Les dictionnaires Python standard ne sont pas ordonnés. Même si vous triiez les paires (clé, valeur), vous ne pourriez pas les stocker dans une variable dict de manière à préserver l'ordre.

Le moyen le plus simple consiste à utiliser OrderedDict , qui se souvient de l'ordre dans lequel les éléments ont été insérés:

In [1]: import collections

In [2]: d = {2:3, 1:89, 4:5, 3:0}

In [3]: od = collections.OrderedDict(sorted(d.items()))

In [4]: od
Out[4]: OrderedDict([(1, 89), (2, 3), (3, 0), (4, 5)])

Peu importe la façon dont od est imprimé; ça va marcher comme prévu:

In [11]: od[1]
Out[11]: 89

In [12]: od[3]
Out[12]: 0

In [13]: for k, v in od.iteritems(): print k, v
   ....: 
1 89
2 3
3 0
4 5

Python 3

Pour les utilisateurs de Python 3, il faut utiliser la fonction .items() au lieu de .iteritems():

In [13]: for k, v in od.items(): print(k, v)
   ....: 
1 89
2 3
3 0
4 5
774
NPE

Les dictionnaires eux-mêmes n’ont pas commandé d’éléments en tant que tels, si vous souhaitez les imprimer, etc. sur un ordre donné, voici quelques exemples:

En Python 2.4 et supérieur:

mydict = {'carl':40,
          'alan':2,
          'bob':1,
          'danny':3}

for key in sorted(mydict):
    print "%s: %s" % (key, mydict[key])

donne:

alan: 2
bob: 1
carl: 40
danny: 3

(Python inférieur à 2.4 :)

keylist = mydict.keys()
keylist.sort()
for key in keylist:
    print "%s: %s" % (key, mydict[key])

Source: http://www.saltycrane.com/blog/2007/09/how-to-sort-python-dictionary-by-keys/

368
James

De la documentation de la bibliothèque collections de Python :

>>> from collections import OrderedDict

>>> # regular unsorted dictionary
>>> d = {'banana': 3, 'Apple':4, 'pear': 1, 'orange': 2}

>>> # dictionary sorted by key -- OrderedDict(sorted(d.items()) also works
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('Apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

>>> # dictionary sorted by value
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('Apple', 4)])

>>> # dictionary sorted by length of the key string
>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('Apple', 4), ('orange', 2), ('banana', 3)])
179
Dennis

Pour python3.6 +, cela se fait facilement avec:

>>> d = {2:3, 1:89, 4:5, 3:0}
>>> dict(sorted(d.items()))
{1: 89, 2: 3, 3: 0, 4: 5}
50
Dipu

Un certain nombre de modules Python fournissent des implémentations de dictionnaire qui gèrent automatiquement les clés dans un ordre trié. Considérez le module sortContainers qui est une implémentation pure-Python et rapide-comme-C. Il existe également une comparaison de performances avec d’autres options populaires comparées les unes aux autres.

L'utilisation d'un dict ordonné est une solution inadéquate si vous devez constamment ajouter et supprimer des paires clé/valeur tout en effectuant une itération.

>>> from sortedcontainers import SortedDict
>>> d = {2:3, 1:89, 4:5, 3:0}
>>> s = SortedDict(d)
>>> s.items()
[(1, 89), (2, 3), (3, 0), (4, 5)]

Le type SortedDict prend également en charge la recherche et la suppression d’emplacement indexé, ce qui n’est pas possible avec le type dict intégré.

>>> s.iloc[-1]
4
>>> del s.iloc[2]
>>> s.keys()
SortedSet([1, 2, 4])
37
GrantJ

Simplement:

d = {2:3, 1:89, 4:5, 3:0}
sd = sorted(d.items())

for k,v in sd:
    print k, v

Sortie:

1 89
2 3
3 0
4 5
24
user3769249

Comme d'autres l'ont mentionné, les dictionnaires sont par nature non ordonnés. Toutefois, si le problème concerne uniquement les dictionnaires affichant de manière ordonnée, vous pouvez remplacer la méthode __str__ dans une sous-classe de dictionnaire et utiliser cette classe de dictionnaire plutôt que la variable intégrée dict. Par exemple.

class SortedDisplayDict(dict):
   def __str__(self):
       return "{" + ", ".join("%r: %r" % (key, self[key]) for key in sorted(self)) + "}"


>>> d = SortedDisplayDict({2:3, 1:89, 4:5, 3:0})
>>> d
{1: 89, 2: 3, 3: 0, 4: 5}

Notez que cela ne change rien à la manière dont les clés sont stockées, à leur ordre de retour lorsque vous les parcourez, etc., à leur affichage dans print ou à la console python.

23
Brian

Trouvé d'une autre manière:

import json
print json.dumps(d, sort_keys = True)

upd:
1. cela trie également les objets imbriqués (merci @DanielF).
2. les dictionnaires python ne sont pas ordonnés, c’est pourquoi ils doivent être imprimés ou assignés à str uniquement.

15
tschesseket

En Python 3. 

>>> D1 = {2:3, 1:89, 4:5, 3:0}
>>> for key in sorted(D1):
    print (key, D1[key])

donne

1 89
2 3
3 0
4 5
14
Evgeny Tryastsin

Ici, j'ai trouvé la solution la plus simple pour trier le dict python par clé en utilisant pprint

>>> x = {'a': 10, 'cd': 20, 'b': 30, 'az': 99} 
>>> print x
{'a': 10, 'b': 30, 'az': 99, 'cd': 20}

mais en utilisant pprint, il retournera un dicté

>>> import pprint 
>>> pprint.pprint(x)
{'a': 10, 'az': 99, 'b': 30, 'cd': 20}
10
Atul Arvind

Le dictionnaire Python était désordonné avant Python 3.6. Dans l'implémentation Python 3.6 de CPython, dictionary conserve l'ordre d'insertion . À partir de Python 3.7, cela deviendra une fonctionnalité de langage.

Si vous voulez trier un dict imbriqué, y compris le sous-dict à l'intérieur, vous pouvez faire:

test_dict = {'a': 1, 'c': 3, 'b': {'b2': 2, 'b1': 1}}

def dict_reorder(item):
    return {k: sort_dict(v) if isinstance(v, dict) else v for k, v in sorted(item.items())}

reordered_dict = dict_reorder(test_dict)

https://Gist.github.com/ligyxy/f60f0374defc383aa098d44cfbd318eb

7
Guangyang Li

Il existe un moyen simple de trier un dictionnaire.

Selon votre question,

La solution est:

c={2:3, 1:89, 4:5, 3:0}
y=sorted(c.items())
print y

(Où c est le nom de votre dictionnaire.)

Ce programme donne la sortie suivante:

[(1, 89), (2, 3), (3, 0), (4, 5)]

comme tu voulais.

Un autre exemple est:

d={"John":36,"Lucy":24,"Albert":32,"Peter":18,"Bill":41}
x=sorted(d.keys())
print x

Donne la sortie: ['Albert', 'Bill', 'John', 'Lucy', 'Peter']

y=sorted(d.values())
print y

Donne la sortie: [18, 24, 32, 36, 41]

z=sorted(d.items())
print z

Donne la sortie:

[('Albert', 32), ('Bill', 41), ('John', 36), ('Lucy', 24), ('Peter', 18)]

Par conséquent, en le changeant en clés, valeurs et éléments, vous pouvez imprimer comme vous le souhaitiez. Cela aide!

6
Sree

Générera exactement ce que vous voulez: 

 D1 = {2:3, 1:89, 4:5, 3:0}

 sort_dic = {}

 for i in sorted(D1):
     sort_dic.update({i:D1[i]})
 print sort_dic


{1: 89, 2: 3, 3: 0, 4: 5}

Mais ce n’est pas le moyen d’écrire, car cela pourrait montrer un comportement distinct avec différents dictionnaires, ce que j’ai appris récemment. C'est pourquoi Tim a suggéré la solution parfaite dans la réponse de ma requête que je partage ici.

from collections import OrderedDict
sorted_dict = OrderedDict(sorted(D1.items(), key=lambda t: t[0]))
5
jax

Vous pouvez créer un nouveau dictionnaire en triant le dictionnaire actuel par clé conformément à votre question.

Ceci est votre dictionnaire

d = {2:3, 1:89, 4:5, 3:0}

Créez un nouveau dictionnaire d1 en triant ce d à l'aide de la fonction lambda

d1 = dict(sorted(d.items(), key = lambda x:x[0]))

d1 doit être {1: 89, 2: 3, 3: 0, 4: 5}, triés en fonction des clés de d.

4
Amit Prafulla

Les dits Python ne sont pas commandés. Habituellement, cela ne pose pas de problème car le cas d'utilisation le plus courant consiste à effectuer une recherche. 

Le moyen le plus simple de faire ce que vous voulez est de créer un collections.OrderedDict en insérant les éléments dans un ordre trié.

ordered_dict = collections.OrderedDict([(k, d[k]) for k in sorted(d.keys())])

Si vous devez effectuer une itération, comme l'ont suggéré d'autres personnes ci-dessus, le moyen le plus simple consiste à effectuer une itération sur des clés triées. Exemples-

Imprimer les valeurs triées par clés:

# create the dict
d = {k1:v1, k2:v2,...}
# iterate by keys in sorted order
for k in sorted(d.keys()):
    value = d[k]
    # do something with k, value like print
    print k, value

Obtenir la liste des valeurs triées par clés:

values = [d[k] for k in sorted(d.keys())]
4
Ramashish Baranwal

Je pense que le plus simple est de trier le dict par clé et de sauvegarder la clé clé triée: valeur dans un nouveau dict.

dict1 = {'renault': 3, 'ford':4, 'volvo': 1, 'toyota': 2} 
dict2 = {}                  # create an empty dict to store the sorted values
for key in sorted(dict1.keys()):
    if not key in dict2:    # Depending on the goal, this line may not be neccessary
        dict2[key] = dict1[key]

Pour le rendre plus clair:

dict1 = {'renault': 3, 'ford':4, 'volvo': 1, 'toyota': 2} 
dict2 = {}                  # create an empty dict to store the sorted     values
for key in sorted(dict1.keys()):
    if not key in dict2:    # Depending on the goal, this line may not be  neccessary
        value = dict1[key]
        dict2[key] = value
4
lallolu

J'arrive avec un tri dicté sur une seule ligne. 

>> a = {2:3, 1:89, 4:5, 3:0}
>> c = {i:a[i] for i in dict.fromkeys(sorted([i for i in a]))}
>> print(c)
{1: 89, 2: 3, 3: 0, 4: 5}
[Finished in 0.4s]

J'espère que cela vous sera utile. 

1
Jeevan Chaitanya

La solution la plus simple est d'obtenir une liste des clés dict, classées par ordre puis itérées sur dict. Par exemple

a1 = {'a':1, 'b':13, 'd':4, 'c':2, 'e':30}
a1_sorted_keys = sorted(a1, key=a1.get, reverse=True)
for r in a1_sorted_keys:
    print r, a1[r]

La suite sera la sortie (ordre décroissant)

e 30
b 13
d 4
c 2
a 1
0
Shafiq

Une comparaison temporelle des deux méthodes de 2.7 montre qu'elles sont pratiquement identiques:

>>> setup_string = "a = sorted(dict({2:3, 1:89, 4:5, 3:0}).items())"
>>> timeit.timeit(stmt="[(k, val) for k, val in a]", setup=setup_string, number=10000)
0.003599141953657181

>>> setup_string = "from collections import OrderedDict\n"
>>> setup_string += "a = OrderedDict({1:89, 2:3, 3:0, 4:5})\n"
>>> setup_string += "b = a.items()"
>>> timeit.timeit(stmt="[(k, val) for k, val in b]", setup=setup_string, number=10000)
0.003581275490432745 
0
Jesuisme

Les gars vous faites des choses compliquées ... c'est vraiment simple

from pprint import pprint
Dict={'B':1,'A':2,'C':3}
pprint(Dict)

La sortie est:

{'A':2,'B':1,'C':3}
0
Derick Fdo

Ou utilisez pandas,

Démo:

>>> d={'B':1,'A':2,'C':3}
>>> df=pd.DataFrame(d,index=[0]).sort_index(axis=1)
   A  B  C
0  2  1  3
>>> df.to_dict('int')[0]
{'A': 2, 'B': 1, 'C': 3}
>>> 

Voir:

Docs de ceci

Documentation de pandas entiers

0
U9-Forward
dictionary = {1:[2],2:[],5:[4,5],4:[5],3:[1]}

temp=sorted(dictionary)
sorted_dict = dict([(k,dictionary[k]) for i,k in enumerate(temp)])

sorted_dict:
         {1: [2], 2: [], 3: [1], 4: [5], 5: [4, 5]}
0
Mahdi Ghelichi

Une autre approche pythonique serait

def sort_dict(my_dict):
    return sorted(my_dict.items(), key=lambda x :x[1])


0
E. Dogan
from operator import itemgetter
# if you would like to play with multiple dictionaries then here you go:
# Three dictionaries that are composed of first name and last name.
user = [
    {'fname': 'Mo', 'lname': 'Mahjoub'},
    {'fname': 'Abdo', 'lname': 'Al-hebashi'},
    {'fname': 'ALi', 'lname': 'Muhammad'}
]
#  This loop will sort by the first and the last names.
# notice that in a dictionary order doesn't matter. So it could put the first name first or the last name first. 
for k in sorted (user, key=itemgetter ('fname', 'lname')):
    print (k)

# This one will sort by the first name only.
for x in sorted (user, key=itemgetter ('fname')):
    print (x)
0
Mohammad Mahjoub