如何以空格对齐方式递归打印 Python 字典及其子字典到列中

问题描述 投票:0回答:2

我想创建一个可以接受字典字典的函数,如下所示

information = {
    "sample information": {
        "ID": 169888,
        "name": "ttH",
        "number of events": 124883,
        "cross section": 0.055519,
        "k factor": 1.0201,
        "generator": "pythia8",
        "variables": {
            "trk_n": 147,
            "zappo_n": 9001
        }
    }
}

然后以如下所示的简洁方式打印它,并使用空格对齐键和值:

sample information:
   ID:                 169888
   name:               ttH
   number of events:   124883
   cross section:      0.055519
   k factor:           1.0201
   generator:          pythia8
   variables:
      trk_n:           147
      zappo_n:         9001

我对该功能的尝试如下:

def printDictionary(
    dictionary = None,
    indentation = ''
    ):
    for key, value in dictionary.iteritems():
        if isinstance(value, dict):
            print("{indentation}{key}:".format(
            indentation = indentation,
            key = key
        ))
            printDictionary(
                dictionary = value,
                indentation = indentation + '   '
            )
        else:
            print(indentation + "{key}: {value}".format(
                key = key,
                value = value
            ))

它产生如下输出:

sample information:
   name: ttH
   generator: pythia8
   cross section: 0.055519
   variables:
      zappo_n: 9001
      trk_n: 147
   number of events: 124883
   k factor: 1.0201
   ID: 169888

如图所示,它成功地递归打印字典的字典,但是没有将值对齐到整齐的列中。对于任意深度的字典,有什么合理的方法可以做到这一点?

dictionary printing tabs alignment whitespace
2个回答
0
投票

尝试使用 pprint 模块。您可以这样做,而不是编写自己的函数:

import pprint
pprint.pprint(my_dict)

请注意,这将在字典周围打印

{
}
等字符,在列表周围打印
[]
等字符,但如果您可以忽略它们,
pprint()
将为您处理所有嵌套和缩进。


0
投票

功能

不是空白,但也很漂亮。这不是我的(我忘了作者),但经过重新设计以更好地理解

from typing import Any


def rec_print(map_obj: dict | Any):
    # Tree variants
    end_tree = "└─ "
    pipe_tree = "│  "
    tee_tree = "├─ "
    blank_tree = "   "

    # Process object repr to pretty print
    def _clear_obj_repr(obj):
        return repr(obj).split("at")[0].replace("<", "").replace(">", "").strip()

    # Recursive tree get
    def _get_recursive_repr(map_obj: dict | Any, name: str = "", header: str = "", last=True):
        # End point in recursion
        if not isinstance(map_obj, dict):
            if "<" in repr(map_obj):
                obj_repr = _clear_obj_repr(map_obj)
            else:
                obj_repr = repr(map_obj)

            return f"{header}{end_tree if last else tee_tree}{name}: {obj_repr}\n"

        # Continue recursion
        result = f"{header}{end_tree if last else tee_tree}{name}\n" # Header of local/global tee
        last_key = list(map_obj.keys())[-1]
        for key, value in map_obj.items():
            inner_result = _get_recursive_repr(
                value,
                name=key,
                header=f"{header}{blank_tree if last else pipe_tree}",
                last=key == last_key,
            )

            result += inner_result[6:] # Add tree leaf, delete first 6 symbols to shift left all tree

        return result

    result = _get_recursive_repr(map_obj)
    print(result[4:]) # Delete first empty header

示例:

rec_print(
    dict(
        f=dict(b=lambda x: x * 2),
        a=1234,
        n=dict(
            p=3,
            g=dict(a=2, h=5),
        ),
    )
)

出:

f
└─ b: function lambda
a: 1234
n
├─ p: 3
└─ g
   ├─ a: 2
   └─ h: 5

对于 attrs 类

from attrs import define, asdict


@define
class A:
    g: str = "wq"
    q: int = 2


@define
class T:
    d: int = 3
    g: A = A()


a = T()
rec_print(asdict(a))

出:

d: 3
g
├─ g: 'wq'
└─ q: 2
© www.soinside.com 2019 - 2024. All rights reserved.