2010-09-17 18 views
36

Je me demande s'il y a un moyen facile de formater des sorties dict telles que celle-ci:Howto sorties chaîne Format dict bien

{ 
    'planet' : { 
    'name' : 'Earth', 
    'has' : { 
     'plants' : 'yes', 
     'animals' : 'yes', 
     'cryptonite' : 'no' 
    } 
    } 
} 

..., où simple str (dict) seulement vous donner tout à fait illisible ...

{'planet' : {'has': {'plants': 'yes', 'animals': 'yes', 'cryptonite': 'no'}, 'name': 'Earth'}} 

pour autant que je sais sur Python je dois écrire beaucoup de code avec beaucoup de cas particuliers et String.replace() appelle, où ce problème lui-même ne semble pas si un peu comme un problème de 1000 lignes.

Veuillez suggérer le moyen le plus simple de formater n'importe quel dict selon cette forme.

Répondre

65

Selon ce vous faites avec la sortie, une option est d'utiliser JSON pour la di évaser.

import json 
x = {'planet' : {'has': {'plants': 'yes', 'animals': 'yes', 'cryptonite': 'no'}, 'name': 'Earth'}} 

print json.dumps(x, indent=2) 

Sortie:

{ 
    "planet": { 
    "has": { 
     "plants": "yes", 
     "animals": "yes", 
     "cryptonite": "no" 
    }, 
    "name": "Earth" 
    } 
} 

La mise en garde de cette approche est que certaines choses ne sont pas sérialisables par JSON. Un code supplémentaire serait nécessaire si la dict contenait des éléments non sérialisables comme des classes ou des fonctions.

+3

Nice, jamais vu ce json indent options :) – ohe

+0

Je voudrais vous donner plus d'un pour cette réponse. Tout simplement génial! Merci mec! – erikbwork

+2

cela ne fonctionne pas si l'une des valeurs est un objet Date par exemple – archmage

27

Utilisez pprint

import pprint 

x = { 
    'planet' : { 
    'name' : 'Earth', 
    'has' : { 
     'plants' : 'yes', 
     'animals' : 'yes', 
     'cryptonite' : 'no' 
    } 
    } 
} 
pp = pprint.PrettyPrinter(indent=4) 
pp.pprint(x) 

Ce sorties

{ 'planet': { 'has': { 'animals': 'yes', 
          'cryptonite': 'no', 
          'plants': 'yes'}, 
        'name': 'Earth'}} 

Jouez avec la mise en forme de pprint et vous pouvez obtenir le résultat souhaité.

+1

Eh bien, il n'a que profondeur, largeur et indent comme paramètres. Je ne vois pas comment faire passer la planète à la ligne suivante. Bien sûr, les résultats PP sont mieux lisibles, mais les newline + approprié_spaces est nessaire pour mon cas. Mais merci de me montrer ce joli paquet. Vient dans très pratique dans d'autres cas. – erikbwork

4
def format(d, tab=0): 
    s = ['{\n'] 
    for k,v in d.items(): 
     if isinstance(v, dict): 
      v = format(v, tab+1) 
     else: 
      v = repr(v) 

     s.append('%s%r: %s,\n' % (' '*tab, k, v)) 
    s.append('%s}' % (' '*tab)) 
    return ''.join(s) 

print format({'has': {'plants': 'yes', 'animals': 'yes', 'cryptonite': 'no'}, 'name': 'Earth'}}) 

Sortie:

{ 
'planet': { 
    'has': { 
    'plants': 'yes', 
    'animals': 'yes', 
    'cryptonite': 'no', 
    }, 
    'name': 'Earth', 
    }, 
} 

Notez que je suppose sorta toutes les clés sont des chaînes ou des objets au moins assez ici

+1

Fonctionne comme prévu. Quoi qu'il en soit, j'espère que quelqu'un pourrait trouver une solution tout-piles inclus. S'il n'y a rien d'autre après le week-end, j'utilise votre solution. Merci de votre aide! – erikbwork

+0

Tombe à la récursion infinie sur les dits auto-inclus. –