5

我有一个pformat()用于将字典转换为字符串的函数(不相关:字符串稍后将插入write()文件中.py)。

所以MY_DCT = {1: 11, 2: 22, 3: 33}会变成这样的字符串:

MY_DCT = {
    1: 11,
    2: 22,
    3: 33}

该功能有2个要求:

  1. 字典项目必须显示在第一行之后。
  2. 元素必须缩进 4 个空格。

这是功能:

import pprint    

def f(obj_name, obj_body_as_dct):

    body = '{\n' + pprint.pformat(obj_body_as_dct, indent=4, width=1)[1:]
    name_and_equal_sign = obj_name + ' = '

    return name_and_equal_sign + body + '\n\n'


d = {1: 11, 2: 22, 3: 33}

print(f('MY_DCT', d))

如果indent=0我得到这个字符串:

MY_DCT = {
1: 11,
2: 22,
3: 33}

如果indent=4我得到这个字符串:

MY_DCT = {
   1: 11,
    2: 22,
    3: 33}

我检查了参数pformat()但我不知道如何在每行上显示正确数量的空格。

我知道我可以使用replace()+' '来修复字符串,但我想知道这些额外的空格是从哪里来的,我是否可以通过正确设置参数来摆脱它(如果这甚至可能的话)。

注意:如果有更好的方法来实现上述目标,请告诉我。

4

3 回答 3

5

indentin的默认值为pformat1,因此键出现在另一个之下。

例如,pformat(d, indent=0, width=1)将导致此字符串:

{1: 11,
2: 22,
3: 33}

indent=1

{1: 11,
 2: 22,
 3: 33}

indent=2

{ 1: 11,
  2: 22,
  3: 33}

第一行总是少一个空格。


由于目标是在第一行之后显示 dict 元素,并且所有元素缩进 4 个空格,因此在第一个元素之前添加一个空格并使用indent=4将适用于某些 dicts(如@logic 所建议的那样)。

然而,像d = {1: {'a': 1, 'b': 2}, 2: 22, 3: 33}这样的字典看起来相当难看,因为indent也会影响深度大于 1 的字典的外观:

MY_DCT = {
    1: {   'a': 1,
           'b': 2},
    #    ^
    #    |
    # ugly
    2: 22,
    3: 33}

最吸引人的解决方案(对于我正在处理的数据)是indent=1为第一个元素保留并添加 3 个空格,为其余元素添加 4 个空格。

def f(obj_name, given_dct):
    """
    Converts given dct (body) to a pretty formatted string.
    Resulting string used for file writing.

    Args:
        obj_name: (str) name of the dict
    Returns:
        (str)
    """

    string = pp.pformat(given_dct, width=1)[1:]

    new_str = ''
    for num, line in enumerate(string.split('\n')):
        if num == 0:
            # (pprint module always inserts one less whitespace for first line)
            # (indent=1 is default, giving everything one extra whitespace)
            new_str += ' '*4 + line + '\n'
        else:
            new_str += ' '*3 + line + '\n'

    return obj_name + ' = {\n' + new_str


s = f(obj_name='MY_DCT', given_dct=d)

导致这个字符串:

MY_DCT = {
    1: {'a': 'aa',
        'b': [1,
              2,
              3]},
    2: 22,
    3: 33}
于 2015-04-06T10:20:56.987 回答
2

参数不是您的打印问题。'\n'添加换行符 ( )时会出现问题。从这个例子可以看出:

import pprint    

def f(obj_name, obj_body_as_dct):

    body = '{' + pprint.pformat(obj_body_as_dct, indent=4, width=1, depth=1)[1:]
    name_and_equal_sign = obj_name + ' = ' + '\n'

    return '"""' + name_and_equal_sign + body + '"""' + '\n\n'


d = {1: 11, 2: 22, 3: 33}

print(f('MY_DCT', d))

这输出:

"""MY_DCT = 
{   1: 11,
    2: 22,
    3: 33}"""

换行符和在{打印的第一行中添加“ ”是为什么只有输出的第一行似乎被一个小空间偏移的原因。

更新#1

在对这些值进行了一些修改后,我能够匹配您想要的输出:

import pprint    

def f(obj_name, obj_body_as_dct):

    body = pprint.pformat(obj_body_as_dct, indent=4, width=1, depth=1)[1:]
    name_and_equal_sign = obj_name 

    return '"""' + name_and_equal_sign + ' = ' + '{' + '\n ' + body +'"""'  + '\n\n'  
                                                        # ^ I added a space in this newline

d = {1: 11, 2: 22, 3: 33}

print(f('MY_DCT', d))

上面的代码输出:

"""MY_DCT = { 
    1: 11,
    2: 22,
    3: 33}"""

因此,从本质上讲,您只需要在换行符中添加一个空格(如代码所示)。

更新#2

按照您在评论中的建议:

试试这个:print(pp.pformat({1:11, 2:22, 3:33}, indent=0, width=1)),缩进从 0 到 2。你会注意到,它在第一行应用了少一个空格。这pformat()是建造的方式。-@用户 5061

我试过这个:

import pprint as pp

for i in range(0,3):
    print(pp.pformat({1:11, 2:22, 3:33}, indent=i, width=1))

它给了我这个输出:

{1: 11,     #Indent = 0 Each entry (except 1) is indented by 0 spaces, because the "{" operator is in the way. 
2: 22,
3: 33}
{1: 11,     #Indent = 1 Each entry is indented by 1 spaces
 2: 22,
 3: 33}
{ 1: 11,    #Indent = 2 Each entry is indented by 2 spaces
  2: 22,
  3: 33}

如您所见,问题仍然存在:“ {
如果不存在,那么缩进将是均匀的。该函数pformat()被编码为针对该字符进行调整。

于 2015-04-01T18:25:44.250 回答
0

Logic's answer让您了解了为什么会出现缩进问题。但是,作为(IMO)一种更简洁的方法,您可以使用json. 此输出假设您所说的元素是指字典元素:

import json
obj_name = 'MY_DCT = '
obj_body_as_dct = {1: 11, 2: 22, 3: 33}

stringy = "\"\"\"" + obj_name + "{" \
          + str(json.dumps(obj_body_as_dct, indent=4, separators=(',', ': ')))[1:] + "\"\"\""
print(stringy)

输出:

"""MY_DCT = {
    "1": 11,
    "2": 22,
    "3": 33
}"""
于 2015-04-01T18:31:55.510 回答