93 votes

Impression lisible d'un dict() python trié par clé

Je voudrais imprimer un dictionnaire python dans un fichier en utilisant PrettyPrinter (pour une meilleure lisibilité) mais faire en sorte que le dictionnaire soit trié par clé dans le fichier de sortie pour améliorer encore la lisibilité. Ainsi :

mydict = {'a':1, 'b':2, 'c':3}
pprint(mydict)

est actuellement imprimé sur

{'b':2,
 'c':3,
 'a':1}

Je voudrais faire un PrettyPrint du dictionnaire mais le trier par clé, par exemple.

{'a':1,
 'b':2,
 'c':3}

Quelle est la meilleure façon de procéder ?

110voto

Nick Craig-Wood Points 18742

En fait, pprint semble trier les clés pour vous sous python2.5.

>>> from pprint import pprint
>>> mydict = {'a':1, 'b':2, 'c':3}
>>> pprint(mydict)
{'a': 1, 'b': 2, 'c': 3}
>>> mydict = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}
>>> pprint(mydict)
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> d = dict(zip("kjihgfedcba",range(11)))
>>> pprint(d)
{'a': 10,
 'b': 9,
 'c': 8,
 'd': 7,
 'e': 6,
 'f': 5,
 'g': 4,
 'h': 3,
 'i': 2,
 'j': 1,
 'k': 0}

Mais pas toujours sous python 2.4

>>> from pprint import pprint
>>> mydict = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}
>>> pprint(mydict)
{'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4}
>>> d = dict(zip("kjihgfedcba",range(11)))
>>> pprint(d)
{'a': 10,
 'b': 9,
 'c': 8,
 'd': 7,
 'e': 6,
 'f': 5,
 'g': 4,
 'h': 3,
 'i': 2,
 'j': 1,
 'k': 0}
>>> 

En lisant le code source de pprint.py (2.5), il trie le dictionnaire en utilisant

items = object.items()
items.sort()

pour une ligne multiple ou ceci pour une ligne unique

for k, v in sorted(object.items()):

avant de tenter d'imprimer quoi que ce soit, donc si votre dictionnaire est trié correctement de cette façon, il devrait imprimer correctement. En 2.4, la seconde sorted() est manquante (elle n'existait pas à l'époque), donc les objets imprimés sur une seule ligne ne seront pas triés.

La réponse semble donc être d'utiliser python2.5, bien que cela n'explique pas vraiment votre résultat dans la question.

Mise à jour de Python3

Joli imprimé par trié clés (lambda x : x[0]) :

for key, value in sorted(dict_example.items(), key=lambda x: x[0]): 
    print("{} : {}".format(key, value))

Pretty print by sorted valeurs (lambda x : x[1]) :

for key, value in sorted(dict_example.items(), key=lambda x: x[1]): 
    print("{} : {}".format(key, value))

27voto

Autre possibilité :

>>> mydict = {'a':1, 'b':2, 'c':3}
>>> import json

Puis avec python2 :

>>> print json.dumps(mydict, indent=4, sort_keys=True) # python 2
{
    "a": 1, 
    "b": 2, 
    "c": 3
}

ou avec python 3 :

>>> print(json.dumps(mydict, indent=4, sort_keys=True)) # python 3
{
    "a": 1, 
    "b": 2, 
    "c": 3
}

16voto

Zweedeend Points 186

Une façon simple d'imprimer le contenu trié du dictionnaire, en Python 3 :

>>> dict_example = {'c': 1, 'b': 2, 'a': 3}
>>> for key, value in sorted(dict_example.items()):
...   print("{} : {}".format(key, value))
... 
a : 3
b : 2
c : 1

L'expression dict_example.items() renvoie des tuples, qui peuvent ensuite être triés par sorted() :

>>> dict_example.items()
dict_items([('c', 1), ('b', 2), ('a', 3)])
>>> sorted(dict_example.items())
[('a', 3), ('b', 2), ('c', 1)]

Voici un exemple pour imprimer le contenu trié des valeurs d'un dictionnaire Python.

for key, value in sorted(dict_example.items(), key=lambda d_values: d_values[1]): 
    print("{} : {}".format(key, value))

15voto

rcoder Points 4517

Le Python pprint en fait, le module déjà trie les dictionnaires par clé. Dans les versions antérieures à Python 2.5, le tri n'était déclenché que sur les dictionnaires dont la représentation en pretty-printed s'étendait sur plusieurs lignes, mais dans 2.5.X et 2.6.X, tous les dictionnaires sont triés.

En général, cependant, si vous écrivez des structures de données dans un fichier et que vous souhaitez qu'elles soient lisibles et inscriptibles par l'homme, vous devriez envisager d'utiliser un autre format comme YAML ou JSON. À moins que vos utilisateurs ne soient eux-mêmes des programmeurs, le fait de leur faire maintenir la configuration ou l'état de l'application vidée via pprint et chargé via eval peut être une tâche frustrante et sujette aux erreurs.

12voto

Scott Foubister Points 111

J'ai écrit la fonction suivante pour imprimer les dicts, les listes et les tuples dans un format plus lisible :

def printplus(obj):
    """
    Pretty-prints the object passed in.

    """
    # Dict
    if isinstance(obj, dict):
        for k, v in sorted(obj.items()):
            print u'{0}: {1}'.format(k, v)

    # List or tuple            
    elif isinstance(obj, list) or isinstance(obj, tuple):
        for x in obj:
            print x

    # Other
    else:
        print obj

Exemple d'utilisation en iPython :

>>> dict_example = {'c': 1, 'b': 2, 'a': 3}
>>> printplus(dict_example)
a: 3
b: 2
c: 1

>>> tuple_example = ((1, 2), (3, 4), (5, 6), (7, 8))
>>> printplus(tuple_example)
(1, 2)
(3, 4)
(5, 6)
(7, 8)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X