2010-09-17 5 views
36

Ich frage mich, ob es eine einfache Möglichkeit, Strings von dict-Ausgänge wie diese zu formatieren:Howto Format dict String Ausgänge schön

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

..., wo ein einfaches str (dict) würden Sie nur geben, ein ziemlich unleserlich ...

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

Für so viel wie ich über Python wissen, würde ich schreiben muß, sieht eine Menge Code mit vielen Sonderfällen und string.replace() aufruft, wo dieses Problem selbst nicht so ähnlich wie ein 1000-Zeilen-Problem.

Bitte schlagen Sie den einfachsten Weg vor, um jedes Diktat entsprechend dieser Form zu formatieren.

Antwort

65

Je nachdem, was Sie tun mit der Ausgabe, eine Option ist die Verwendung von JSON für die di spreizen.

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

print json.dumps(x, indent=2) 

Ausgang:

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

Der Nachteil dieses Ansatzes ist, dass einige Dinge von JSON nicht serialisierbar sind. Ein zusätzlicher Code wäre erforderlich, wenn das Dict nicht serialisierbare Elemente wie Klassen oder Funktionen enthält.

+3

Schön, noch nie gesehen, diese JSZ Einzug Optionen :) – ohe

+0

Ich möchte Ihnen mehr als eine Antwort für diese Antwort geben. Einfach super! Danke, Mann! – erikbwork

+2

funktioniert es nicht, wenn einer der Werte ein Date-Objekt ist, zum Beispiel – archmage

27

Verwenden pprint

import pprint 

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

Diese gibt

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

mit pprint Formatierung Spielen Sie herum und Sie können das gewünschte Ergebnis erhalten.

+1

Nun, es hat nur Tiefe, Breite und Einzug als Parameter. Ich sehe keine Möglichkeit, den Planeten in die nächste Linie zu bringen. Klar, PP Ergebnisse sind besser lesbar, aber die Newline + appropriate_spaces ist für meinen Fall notwendig. Aber danke, dass du mir dieses schöne Paket gezeigt hast. In anderen Fällen sehr praktisch. – 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'}}) 

Ausgang:

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

Bitte beachte, dass ich sorta nehme an alle Tasten Strings sind, oder zumindest ziemlich Objekte hier

+1

Funktioniert wie erwartet. Wie auch immer, ich hoffe, dass jemand eine Lösung findet, die alle Batterien enthält. Wenn es nach dem Wochenende nichts anderes mehr gibt, benutze ich deine Lösung. Danke für Ihre Hilfe! – erikbwork

+0

Fällt auf unendliche Rekursion auf Selbst-einschließlich dicts. –