【问题标题】:Python dictionary formattingPython 字典格式化
【发布时间】:2011-02-14 10:58:56
【问题描述】:

我创建了一个 Python 函数来将字典转换为格式化字符串。我的目标是让一个函数接受一个字典作为输入,然后把它变成一个看起来不错的字符串。例如,{'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'}}?如果您提供解决方案,能否告诉我需要如何更改代码(如果确实需要更改)。
注意:我使用的是 python 2.5

【问题讨论】:

标签: python formatting printing dictionary


【解决方案1】:

您可以简单地在字典中存储一个列表。此外,最好不要使用全局来存储缩进。大致如下:

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

【讨论】:

  • 如何使用这个功能?
  • 使用您的示例,您可以将字典定义为 d = {'blah':['hi', {'hello':'hello again'}]} 换句话说,这些值可以是字典、列表或字符串。然后调用 format_dict(d)。
【解决方案2】:

您可以将字典表示为具有子列表:

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

这样做的结果是每个字典将只有一个键值对。从好的方面来说,这意味着您可以拥有重复的键和确定的顺序,就像 XML 一样。

编辑:再想一想,您可以简单地将 'hello''goodbye' 折叠到一个字典中,尽管我个人认为这很令人困惑,因为您现在可以将有序和无序的东西混在一起.所以我猜每个字典一键规则更像是一个建议而不是一个要求。

【讨论】:

    【解决方案3】:

    为什么不直接使用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)
    

    【讨论】:

    • 首先,我没有安装yaml(不知道能不能安装)。其次,这就是我想要的,因为如果您的示例是正确的,那么二级字典也不会被处理,而是显示为“item: {Blah: Hello}”。
    • 好的,我想以防万一。
    【解决方案4】:

    字典是一种映射,因此您不能拥有没有值的键。但是,最接近该值的是具有None 值的键。然后在if not type(d[key]) == type({}): 行和continue 之前添加对None 的检查,以避免打印该值。顺便说一句,那条线会更好if not isinstance(d[key], dict):

    【讨论】:

      【解决方案5】:

      如前所述,只要您希望文本和字典处于同一级别,就需要使用列表作为值。这是一些打印您需要的代码。

      # -*- coding: utf-8 -*-
      #!/usr/bin/env python2.5
      # http://stackoverflow.com/questions/2748378/python-dictionary-formating
      
      def pretty_dict(d, indent=0, spacer='.'):
          """
          takes a dict {'text':'Hello', 'blah':{'hi':'hello','hello':'hi'}}
          And prints:
      
          text:
              Hello
          blah:
              hi:
                  hello
              hello:
                  hi
      
          """
          kindent = spacer * indent
      
          if isinstance(d, basestring):
              return kindent + d
      
          if isinstance(d, list):
              return '\n'.join([(pretty_dict(v, indent, spacer)) for v in d])
      
          return '\n'.join(['%s%s:\n%s' % (kindent, k, pretty_dict(v, indent + 1, spacer)) 
              for k, v in d.items()])
      
      
      test_a = {'text':'Hello', 'blah':{'hi':'hello','hello':'hi'}}
      test_b = {'key with text content':'some text', 'key with dict content':
          {'cheese': 'text', 'item':{'Blah': 'Hello'}}}
      test_c = {'blah':['hi', {'hello':'hello again'}]}
      test_d = {'blah': [
          'hi',
          {'hello':[
              'hello again'
          ]},
          {'goodbye':[
              'hasta la vista, baby'
      ]}
      ]}
      
      
      if __name__ == '__main__':
          print pretty_dict(test_a)
          print pretty_dict(test_b)
          print pretty_dict(test_c)
          print pretty_dict(test_d)
      

      【讨论】:

        【解决方案6】:

        为什么不使用漂亮的打印,它已经完成了这一切?

        http://docs.python.org/dev/library/pprint.html

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-12-21
          • 2022-01-27
          • 2018-05-24
          • 2016-12-06
          • 2019-09-25
          • 1970-01-01
          • 1970-01-01
          • 2018-04-05
          相关资源
          最近更新 更多