Python 字典格式化

4 投票
6 回答
10308 浏览
提问于 2025-04-15 22:13

我写了一个Python函数,用来把字典转换成格式化的字符串。我的目标是让这个函数接收一个字典,然后把它变成一个看起来不错的字符串。比如,像 {'text':'Hello', 'blah':{'hi':'hello','hello':'hi'}} 这样的字典,会被转换成这样:

text:
    Hello
blah:
    hi:
        hello
    hello:
        hi

这是我写的代码:

indent = 0

def format_dict(d):
    global indent
    res = ""
    for key in d:
        res += ("   " * indent) + key + ":\n"
        if not type(d[key]) == type({}):
            res += ("   " * (indent + 1)) + d[key] + "\n"
        else:
            indent += 1
            res += format_dict(d[key])
            indent -= 1
    return res
#test
print format_dict({'key with text content':'some text', 
                  'key with dict content':
                  {'cheese': 'text', 'item':{'Blah': 'Hello'}}})

这个函数运行得很好。它会检查字典里的每一项,如果这一项还是一个字典,它就会继续处理这个字典;如果不是字典,它就会直接把这个值用上。不过,我遇到了一个问题:我不能在字典的某一项里同时放一个字典和一个字符串。比如,如果我想要:

blah:
    hi
    hello:
        hello again

这样就没办法实现了。有没有什么办法可以在字典里放一个像列表那样的项?比如像这样 {'blah':{'hi', 'hello':'hello again'}}?如果你能提供解决方案的话,能告诉我需要怎么修改我的代码吗(如果需要修改的话)。
注意: 我使用的是Python 2.5

6 个回答

2

为什么不直接使用 yaml 呢?

import yaml
import StringIO

d = {'key with text content':'some text', 
     'key with dict content':
     {'cheese': 'text', 'item': {'Blah': 'Hello'}}}
s = StringIO.StringIO()
yaml.dump(d, s)
print s.getvalue()

这段代码的输出是:

key with dict content:
  cheese: text
  item: {Blah: Hello}
key with text content: some text

而且你可以把它重新加载到一个字典里

s.seek(0)
d = yaml.load(s)
2

你可以把字典看作是有一系列子项的列表:

{'blah': [
    'hi',
    {'hello':[
        'hello again'
    ]},
    {'goodbye':[
        'hasta la vista, baby'
    ]}
]}

这样做的结果是,每个字典只会有一个键值对。好处是,这样你可以有重复的键,并且顺序是确定的,就像XML一样。

补充说明:再想想,你其实可以把 'hello''goodbye' 合并成一个字典,虽然我个人觉得这样会有点混乱,因为这会让你有有序和无序的内容混在一起。所以我想,每个字典只用一个键的规则更像是个建议,而不是硬性规定。

2

你可以直接在字典里存一个列表。而且,最好不要用全局变量来存缩进。可以这样做:

def format_value(v, indent):
    if isinstance(v, list):
         return ''.join([format_value(item, indent) for item in v])
    elif isinstance(v, dict):
         return format_dict(v, indent)
    elif isinstance(v, str):
         return ("   " * indent) + v + "\n"

def format_dict(d, indent=0):
    res = ""
    for key in d:
        res += ("   " * indent) + key + ":\n"
        res += format_value(d[key], indent + 1)
    return res

撰写回答