【问题标题】:Python format print with a list带有列表的 Python 格式打印
【发布时间】:2014-12-15 18:24:04
【问题描述】:

这是产生我的输出的最 Pythonic 的方式。让我说明我试图实现的行为。 对于我的一个项目,我正在构建一个函数,该函数采用不同的参数来打印列中的输出。 其接收的列表示例。

[('Field', 'Integer', 'Hex'), 
('Machine;', 332, '0x14c'), 
('NumberOfSections;', 9, '0x9'), 
('Time Date Stamp;', 4, '0x4'), 
('PointerToSymbolTable;', 126976, '0x1f000')

** 项目的大小可以不同(现在每个元组只有 3 个项目,另一个列表可以是 4 个或任何数量**

输出应该是这样的

Field                                                     Integer      Hex           
-------------------------------------------------------------------------------
Machine;                                                  332          0x14c        
NumberOfSections;                                         9            0x9          
Time Date Stamp;                                          4            0x4          
PointerToSymbolTable;                                     126976       0x1f000

出于工作目的,我创建了一个仅包含标题字段的列表: 这不是必需的,但它使尝试一些东西变得更容易了

Header field is ['Field', 'Integer', 'Hex']  

列表中的第一个元组声明了所谓的“标题字段”,如列表示例所示。 对于这种情况,只有 3 个项目,但这可能会不时发生变化。所以我尝试用以下方法计算项目的大小:

length_container_header = len(container[0])

此变量可用于正确构建输出。 构建标题“打印”我会构建这样的东西。

print("{:21} {:7} {:7}".format(header_field[0], header_field[1], header_field[2]))

现在这是一个关于它应该如何的手动版本。正如您注意到的那样,标题字段“字段”更短 列表中的 PointerToSymbolTable。我编写了这个函数来确定列表中每个位置的最长项目

container_lenght_list = []    
    local_l = 0    
    for field in range(0, lenght_container_body):
        for item in container[1:]:
            if len(str(item[field])) > local_l:
                local_l = len(str(item[field]))
            else:
                continue
        container_lenght_list.append(str(local_l))
        local_l = 0

在这种情况下产生一个类似于 [21, 7, 7] 的列表。 创建格式字符串非常简单,

formatstring = ""

for line in lst:
    formatstring+= "{:" + str(line) +"}"

产生字符串:

 {:21}{:7}{:7}

这部分是有问题的,我怎样才能产生格式字符串的最后一部分? 我在 format() 函数中尝试了一个嵌套的 for 循环,但最终出现了各种错误。我认为可以通过 for循环,我只是不知道怎么做。如果有人可以将我推向正确的方向打印标题,我将不胜感激。一旦我弄清楚如何打印标题,我几乎可以弄清楚其余部分。我希望我解释得足够好

致以诚挚的问候,

【问题讨论】:

  • programmingforums.org/post195293.html 看底部。您将使用您的格式作为示例中的 row 变量。然后遍历列表以获取每一行,即args
  • “格式字符串的最后一部分”到底是什么意思?你能举个简短的例子吗?
  • 我认为他不知道如何将他的列表值应用于格式。但是,是的,我不完全确定。上面有很多话。
  • 是的,格式后的部分(,会尝试你的链接阴沉的thkx

标签: python string list format


【解决方案1】:

You can use * to unpack argument list:

container = [
    ('Field', 'Integer', 'Hex'), 
    ('Machine;', 332, '0x14c'), 
    ('NumberOfSections;', 9, '0x9'), 
    ('Time Date Stamp;', 4, '0x4'), 
    ('PointerToSymbolTable;', 126976, '0x1f000')
]
lengths = [
    max(len(str(row[i])) for row in container) for i in range(len(container[0]))
] # => [21, 7, 7]
# OR  lengths = [max(map(len, map(str, x))) for x in zip(*container)]
fmt = ' '.join('{:<%d}' % l for l in lengths)
# => '{:<21} {:<7} {:<7}'    # < for left-align

print(fmt.format(*container[0]))  # header
print('-' * (sum(lengths) + len(lengths) - 1))  # separator
for row in container[1:]:
    print(fmt.format(*row))  # <------- unpacking argument list
    # similar to   print(fmt.format(row[0], row[1], row[2])

输出:

Field                 Integer Hex
-------------------------------------
Machine;              332     0x14c
NumberOfSections;     9       0x9
Time Date Stamp;      4       0x4
PointerToSymbolTable; 126976  0x1f000

【讨论】:

  • 谢谢,从来不知道 * 存在。它也在 gloomy.penguins 的链接中。哦,感谢长度功能,更短
【解决方案2】:

以表格形式格式化数据需要四个重要步骤

  1. 确定字段布局,即按行或按列表示数据。根据您可能需要使用zip 转置数据的决定
  2. 确定字段大小。除非您想硬编码字段大小(不推荐),否则您实际上应该根据数据确定最大字段大小,允许在字段之间进行自定义填充。通常这需要读取数据并确定字段的最大长度[len(max(map(str, field), key = len)) + pad for field in zip(*data)]
  3. 提取标题行。这很容易,因为它只需要索引第 0 行,即data[0]
  4. 格式化数据。这需要对python format string有所了解

实施

class FormatTable(object):
    def __init__(self, data, pad = 2):
        self.data = data
        self.pad = pad
        self.header = data[0]
        self.field_size = [len(max(map(str, field), key = len)) + pad 
                           for field in zip(*data)]
        self.format = ''.join('{{:<{}}}'.format(s) for s in self.field_size)
    def __iter__(self):
        yield ''.join(self.format.format(*self.header))
        yield '-'*(sum(self.field_size) + self.pad * len(self.header))
        for row in data[1:]:
            yield ''.join(self.format.format(*row))

演示

for row in FormatTable(data):
    print row

Field                  Integer  Hex      
-----------------------------------------------
Machine;               332      0x14c    
NumberOfSections;      9        0x9      
Time Date Stamp;       4        0x4      
PointerToSymbolTable;  126976   0x1f000 

【讨论】:

    【解决方案3】:

    我不知道它是否是“Pythonic”,但你可以使用pandas 来格式化你的输出。

    import pandas as pd
    
    data = [('Field', 'Integer', 'Hex'),
    ('Machine;', 332, '0x14c'),
    ('NumberOfSections;', 9, '0x9'),
    ('Time Date Stamp;', 4, '0x4'),
    ('PointerToSymbolTable;', 126976, '0x1f000')]
    
    s = pd.DataFrame(data[1:], columns=data[0])
    print s.to_string(index=False)
    

    结果:

                     Field  Integer      Hex
                  Machine;      332    0x14c
         NumberOfSections;        9      0x9
          Time Date Stamp;        4      0x4
     PointerToSymbolTable;   126976  0x1f000
    

    【讨论】:

    • 您正在使用另一个库“Pandas”!接受的解决方案是纯python!
    猜你喜欢
    • 2021-12-31
    • 2013-10-24
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多