Any way to properly pretty-print ordered dictionaries?

后端 未结 15 1427
春和景丽
春和景丽 2020-12-07 14:34

I like the pprint module in Python. I use it a lot for testing and debugging. I frequently use the width option to make sure the output fits nicely within my terminal window

15条回答
  •  时光说笑
    2020-12-07 14:54

    This is pretty crude, but I just needed a way to visualize a data structure made up of any arbitrary Mappings and Iterables and this is what I came up with before giving up. It's recursive, so it will fall through nested structures and lists just fine. I used the Mapping and Iterable abstract base classes from collections to handle just about anything.

    I was aiming for almost yaml like output with concise python code, but didn't quite make it.

    def format_structure(d, level=0):
        x = ""
        if isinstance(d, Mapping):
            lenk = max(map(lambda x: len(str(x)), d.keys()))
            for k, v in d.items():
                key_text = "\n" + " "*level + " "*(lenk - len(str(k))) + str(k)
                x += key_text + ": " + format_structure(v, level=level+lenk)
        elif isinstance(d, Iterable) and not isinstance(d, basestring):
            for e in d:
                x += "\n" + " "*level + "- " + format_structure(e, level=level+4)
        else:
            x = str(d)
        return x
    

    and some test data using OrderedDict and lists of OrderedDicts... (sheesh Python needs OrderedDict literals sooo badly...)

    d = OrderedDict([("main",
                      OrderedDict([("window",
                                    OrderedDict([("size", [500, 500]),
                                                 ("position", [100, 900])])),
                                   ("splash_enabled", True),
                                   ("theme", "Dark")])),
                     ("updates",
                      OrderedDict([("automatic", True),
                                   ("servers",
                                    [OrderedDict([("url", "http://server1.com"),
                                                  ("name", "Stable")]),
                                     OrderedDict([("url", "http://server2.com"),
                                                  ("name", "Beta")]),
                                     OrderedDict([("url", "http://server3.com"),
                                                  ("name", "Dev")])]),
                                   ("prompt_restart", True)])),
                     ("logging",
                      OrderedDict([("enabled", True),
                                   ("rotate", True)]))])
    
    print format_structure(d)
    

    yields the following output:

       main: 
                   window: 
                             size: 
                                 - 500
                                 - 500
                         position: 
                                 - 100
                                 - 900
           splash_enabled: True
                    theme: Dark
    updates: 
                automatic: True
                  servers: 
                         - 
                              url: http://server1.com
                             name: Stable
                         - 
                              url: http://server2.com
                             name: Beta
                         - 
                              url: http://server3.com
                             name: Dev
           prompt_restart: True
    logging: 
           enabled: True
            rotate: True
    

    I had some thoughts along the way of using str.format() for better alignment, but didn't feel like digging into it. You'd need to dynamically specify the field widths depending on the type of alignment you want, which would get either tricky or cumbersome.

    Anyway, this shows me my data in readable hierarchical fashion, so that works for me!

提交回复
热议问题