120 votes

Un moyen d'imprimer correctement les dictionnaires ordonnés en Python?

J'aime la pprint module en Python. Je l'utilise beaucoup pour les tests et le débogage. J'utilise fréquemment la largeur option pour assurer que la sortie s'intègre bien dans ma fenêtre de terminal.

Il a bien fonctionné jusqu'à ce que ils ont ajouté une nouvelle commandés type de dictionnaire en Python 2.7 (autre fonctionnalité que j'aime vraiment). Si j'essaie de l'à-peu-près de l'impression d'un ordre du dictionnaire, ce n'est pas bien. Au lieu d'avoir chaque paire clé-valeur sur sa propre ligne, le tout s'affiche sur une longue ligne, qui s'enroule plusieurs fois et est difficile à lire.

Est-ce quelqu'un ici a une manière de le faire imprimer joliment, comme le vieux non ordonnée des dictionnaires? Je pourrais sans doute trouver quelque chose, éventuellement à l'aide du PrettyPrinter.méthode de mise en forme, si je passe assez de temps, mais je me demandais si quelqu'un ici connaît déjà une solution.

Mise à JOUR: j'ai déposé un rapport de bug pour cela. Vous pouvez le voir à http://bugs.python.org/issue10592.

152voto

webwurst Points 1125

En guise de solution temporaire, vous pouvez essayer le dumping au format JSON. Vous perdez certaines informations de type, mais elles sont belles et respectent l'ordre.

 import json

pprint(data, indent=4)
# ^ugly

print(json.dumps(data, indent=4))
# ^nice
 

20voto

kzh Points 5098

Ce qui suit fonctionnera si l'ordre de votre OrderedDict est un tri alpha, car pprint triera un dict avant impression.

 pprint(dict(o.items()))
 

9voto

martineau Points 21665

Voici une autre réponse qui fonctionne en remplaçant et en utilisant le stock pprint() fonction en interne. Contrairement à mon précédent il va manipuler OrderedDict'à l'intérieur d'un autre conteneur comme un list et doit gérer n'importe quel mot-clé facultatif arguments -- toutefois, il n'a pas le même degré de contrôle sur la sortie que les autres moyens.

Il fonctionne en redirigeant le stock de la fonction de sortie dans un tampon temporaire, puis word enveloppe avant de l'envoyer sur le flux de sortie. Alors que la sortie finale produite n'est pas toujours vrai assez, il peut être assez "bon" pour l'utiliser comme une solution de contournement.

Mise à jour

Simplifiée par l'utilisation de la bibliothèque standard textwrap module.

from collections import OrderedDict
from cStringIO import StringIO
from pprint import pprint as pp_pprint
import sys
import textwrap

def pprint(object, **kwrds):
    try:
        width = kwrds['width']
    except KeyError: # unlimited, use stock function
        pp_pprint(object, **kwrds)
        return
    buffer = StringIO()
    stream = kwrds.get('stream', sys.stdout)
    kwrds.update({'stream': buffer})
    pp_pprint(object, **kwrds)
    words = buffer.getvalue().split()
    buffer.close()

    # word wrap output onto multiple lines <= width characters
    print >> stream, textwrap.fill(' '.join(words), width=width)

d = dict((('john',1), ('paul',2), ('mary',3)))
od = OrderedDict((('john',1), ('paul',2), ('mary',3)))
lod = [OrderedDict((('john',1), ('paul',2), ('mary',3))),
       OrderedDict((('moe',1), ('curly',2), ('larry',3))),
       OrderedDict((('weapons',1), ('mass',2), ('destruction',3)))]

pprint(d, width=40)
# {'john': 1, 'mary': 3, 'paul': 2}

pprint(od, width=40)
# OrderedDict([('john', 1), ('paul', 2),
# ('mary', 3)])

pprint(lod, width=40)
# [OrderedDict([('john', 1), ('paul', 2),
# ('mary', 3)]), OrderedDict([('moe', 1),
# ('curly', 2), ('larry', 3)]),
# OrderedDict([('weapons', 1), ('mass',
# 2), ('destruction', 3)])]

2voto

Jakob Bowyer Points 12873
 def pprint_od(od):
    print "{"
    for key in od:
        print "%s:%s,\n" % key, od[key]
    print "}"
 

Voilà

 for item in li:
    pprint_od(item)
 

ou

 (pprint_od(item) for item in li)
 

1voto

Bill M. Points 1

La méthode pprint() invoque simplement la méthode __repr__() des éléments qu’elle contient, et OrderedDict ne semble pas faire grand chose dans sa méthode (ou n’a pas un ou quelque chose).

Voici une solution peu coûteuse qui devrait fonctionner si vous ne vous souciez pas de l'ordre visible dans la sortie du tirage , qui peut être un gros si:

 class PrintableOrderedDict(OrderedDict):
    def __repr__(self):
        return dict.__repr__(self)
 

Je suis en fait surpris que l'ordre ne soit pas préservé ... ah bien.

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