【问题标题】:pretty printer with Python?Python 的漂亮打印机?
【发布时间】:2010-09-13 03:54:36
【问题描述】:

我有一个标签列表,数据如下。

['id', '版本', 'chip_name', 'xversion', 'device', 'opt_param', 'place_effort'] [1, 1.0, u'virtex2', u'xilinx11.5', u'xc5vlx50', u'Speed', u'High']

我需要将它们打印到控制台中。为此,我正在遍历列表,并使用制表符 ('\t') 打印出每个元素。

但是,不幸的是,结果并不那么漂亮。

数据数 1 和列数 7 id 版本芯片名称 xversion 设备 opt_param place_effort 1 1.0 virtex2 xilinx11.5 xc5vlx50 速度高

label和data的字符串长度参差不齐,对齐不好。

有没有办法用 Python 解决这个问题?

添加

在 Mike DeSimone 的回答的帮助下,我可以制作出可用于我的目的的漂亮打印机。 valueResults 是一个双重列表。

    labels = queryResult.names
    valueResults = queryResult.result

    # get the maximum width
    allData = valueResults
    allData.insert(0,labels)
    transpose = zip(*valueResults) # remove the sequence as a parameter
    #print transpose
    for value in transpose:
        # value is integer/float/unicode/str, so make it length of str
        newValue = [len(str(i)) for i in value]
        columnWidth = max(newValue)
        columnWidths.append(columnWidth)
        dividers.append('-' * columnWidth)
        dblDividers.append('=' * columnWidth)
        label = value[0]
        paddedLabels.append(label.center(columnWidth))

    paddedString = ""

    for values in valueResults[1:]:
        paddedValue = []
        for i, value in enumerate(values):
            svalue = str(value)
            columnWidth = columnWidths[i]
            paddedValue.append(svalue.center(columnWidth))
        paddedString += '| ' + ' | '.join(paddedValue) + ' |' + '\n'

    string += '+-' + '-+-'.join(dividers) + '-+' + '\n'
    string += '| ' + ' | '.join(paddedLabels) + ' |' + '\n'
    string += '+=' + '=+='.join(dblDividers) + '=+' + '\n'
    string += paddedString
    string += '+-' + '-+-'.join(dividers) + '-+' + '\n'

这就是结果。

+----+---------+------------+------------+--------- -+------------+-------------+ |编号 |版本 |芯片名 |版本 |设备 |选择参数 | place_effort | +====+=========+============+============+========= =+============+===============+ | 1 | 1.0 | virtex2 |赛灵思11.5 | xc5vlx50 |速度 |高 | | 2 | 1.0 | virtex2 |赛灵思11.5 | xc5vlx50 |速度 |高 | +----+---------+------------+------------+--------- -+------------+-------------+

感谢您的帮助。

【问题讨论】:

    标签: python pretty-print


    【解决方案1】:

    在打印出来之前使用 ljust 填充内容。

    import sys
    
    def maxwidth(table, index):
        """Get the maximum width of the given column index"""
        return max([len(str(row[index])) for row in table])
    
    def pprint_table(table):
        colpad = []
    
        for i in range(len(table[0])):
            colpad.append(maxwidth(table, i))
    
        for row in table:
            print str(row[0]).ljust(colpad[0] + 1),
            for i in range(1, len(row)):
                col = str(row[i]).rjust(colpad[i] + 2)
                print "", col,
            print ""
    
    a = ['id', 'Version', 'chip_name', 'xversion', 'device', 'opt_param', 'place_effort']
    b = [1, 1.0, u'virtex2', u'xilinx11.5', u'xc5vlx50', u'Speed', u'High']
    
    # Put it in the table
    
    c = [a, b]
    
    pprint_table(c)
    

    输出:

    id     Version    chip_name      xversion      device    opt_param    place_effort 
    1          1.0      virtex2    xilinx11.5    xc5vlx50        Speed            High
    

    【讨论】:

    • 一个允许 pprint_table 与 python2/3 一起工作的小修复:def pprint_table(table): colpad = [] side_spaces=3 for i in range(len(table[0])): colpad.append(maxwidth(table, i)) for row in table: sys.stdout.write(str(row[0]).ljust(colpad[0] + 1)) for i in range(1, len(row)): col = str(row[i]).rjust(colpad[i] + side_spaces) sys.stdout.write(str(''+ col)) print ('')
    【解决方案2】:

    类似这样的:

    labels = ['id', 'Version', 'chip_name', 'xversion', 'device', 'opt_param', 
        'place_effort']
    values = [1, 1.0, u'virtex2', u'xilinx11.5', u'xc5vlx50', u'Speed', u'High']
    
    paddedLabels = []
    paddedValues = []
    
    for label, value in zip(labels, values):
        value = str(value)
        columnWidth = max(len(label), len(value))
        paddedLabels.append(label.center(columnWidth))
        paddedValues.append(value.center(columnWidth))
    
    print ' '.join(paddedLabels)
    print ' '.join(paddedValues)
    

    输出:

    id Version chip_name  xversion   device  opt_param place_effort
    1    1.0    virtex2  xilinx11.5 xc5vlx50   Speed       High
    

    如果你想变得花哨,就让它reStructuredText-ready:

    labels = ['id', 'Version', 'chip_name', 'xversion', 'device', 'opt_param', 
        'place_effort']
    values = [1, 1.0, u'virtex2', u'xilinx11.5', u'xc5vlx50', u'Speed', u'High']
    
    paddedLabels = []
    paddedValues = []
    dividers = []
    dblDividers = []
    
    for label, value in zip(labels, values):
        value = str(value)
        columnWidth = max(len(label), len(value))
        paddedLabels.append(label.center(columnWidth))
        paddedValues.append(value.center(columnWidth))
        dividers.append('-' * columnWidth)
        dblDividers.append('=' * columnWidth)
    
    print '+-' + '-+-'.join(dividers) + '-+'
    print '| ' + ' | '.join(paddedLabels) + ' |'
    print '+=' + '=+='.join(dblDividers) + '=+'
    print '| ' + ' | '.join(paddedValues) + ' |'
    print '+-' + '-+-'.join(dividers) + '-+'
    

    输出:

    +----+---------+-----------+------------+----------+-----------+--------------+
    | id | Version | chip_name |  xversion  |  device  | opt_param | place_effort |
    +====+=========+===========+============+==========+===========+==============+
    | 1  |   1.0   |  virtex2  | xilinx11.5 | xc5vlx50 |   Speed   |     High     |
    +----+---------+-----------+------------+----------+-----------+--------------+
    

    【讨论】:

    • 如果值的长度不同,这将导致列宽不均匀。您需要找到 all 值(和标题标签)的最大值,以了解每列的宽度。
    • 我以为 prosseek 会想出那么多。我的回答集中在zipstr.centerstr.join的使用上。
    【解决方案3】:

    你可以试试这个

    >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
    >>> for name, phone in table.items():
    ...     print '{0:10} ==> {1:10d}'.format(name, phone)
    ...
    Jack       ==>       4098
    Dcab       ==>       7678
    Sjoerd     ==>       4127
    

    来自http://docs.python.org/tutorial/inputoutput.html

    : 后面的整数是填充。

    或者更好

    >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
    >>> print ('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '
    ...        'Dcab: {0[Dcab]:d}'.format(table))
    Jack: 4098; Sjoerd: 4127; Dcab: 8637678
    

    【讨论】:

      【解决方案4】:

      【讨论】:

        【解决方案5】:

        另一种解决方案是完全不使用制表符,使用空格来调整列宽,也不需要手动填充,因为'%Ns'字符串格式很方便,例如

        header = ['id', 'Version', 'chip_name', 'xversion', 'device', 'opt_param', 'place_effort']
        rows = [[1, 1.0, u'virtex2', u'xilinx11.5', u'xc5vlx50', u'Speed', u'High']]
        
        def print_row(row):
            column_width=12
            format_str = ("%-"+str(column_width)+"s")*len(row)
            print format_str%tuple(row)
        
        print_row(header)
        for row in rows:
            print_row(row)
        

        输出:

        id          Version     chip_name   xversion    device      opt_param   place_effort
        1           1.0         virtex2     xilinx11.5  xc5vlx50    Speed       High
        

        【讨论】:

          【解决方案6】:

          为了快速解决,如果 ln 是包含所有这些列表的列表,

          for l in ln:
              print "\t".join([str(x).ljust(10) for x in l])
          

          将打印由制表符分隔并左对齐的列。如果它还不够漂亮,就增加它里面的值。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-05-12
            • 1970-01-01
            • 1970-01-01
            • 2011-07-02
            • 1970-01-01
            • 2020-11-10
            • 2019-04-23
            相关资源
            最近更新 更多