красивый принтер с Python?

У меня есть список меток и данных следующим образом.

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

Мне нужно распечатать их в консоли. И для этого я перебираю список и распечатываю каждый элемент с вкладкой ('\ t').

Но, к сожалению, результат не такой красивый.


number of data 1 and number of column 7
id      Version     chip_name       xversion        device      opt_param       place_effort        
1       1.0     virtex2     xilinx11.5      xc5vlx50        Speed       High        

Длина строки метки и данных весьма изменчива и плохо выровнена.

Есть ли решение этой проблемы с Python?

ДОБАВЛЕН

Благодаря ответу Майка Дезимоуна я мог бы сделать красивый принтер, который я могу использовать для своих целей. 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'

И это результат.


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

Спасибо за помощь.


person prosseek    schedule 13.09.2010    source источник


Ответы (6)


Что-то вроде этого:

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:

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     |
+----+---------+-----------+------------+----------+-----------+--------------+
person Mike DeSimone    schedule 13.09.2010
comment
Это приведет к неравномерной ширине столбцов, если значения имеют разную длину. Вам нужно будет найти максимальное значение всех (и метку заголовка), чтобы узнать, насколько широким должен быть каждый столбец. - person Jason Hall; 13.09.2010
comment
Я полагал, что prosseek догадается об этом. Мой ответ сосредоточен на использовании zip, str.center и str.join. - person Mike DeSimone; 13.09.2010

Используйте 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
person pyfunc    schedule 13.09.2010
comment
Небольшое исправление для разрешения работы 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 ('') - person Rfraile; 19.09.2015

ты мог бы попробовать это

>>> 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
person Rohan Monga    schedule 13.09.2010

Вы можете использовать готовое решение: prettytable Простая библиотека Python для удобного отображения табличных данных в визуально привлекательной таблице ASCII. формат

Другие решения, см. мои похожие вопросы, другие ответы: Как расширить красивый модуль печати к столам?

person Tony Veijalainen    schedule 13.09.2010

Другое решение - вообще не использовать вкладку и использовать пробелы для настройки ширины столбца, а также отсутствие необходимости заполнения вручную, поскольку форматирование строки «%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
person Anurag Uniyal    schedule 13.09.2010

Для быстрого решения, если ln - это список, содержащий все эти списки,

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

будет печатать столбцы, разделенные табуляцией и выровненные по левому краю. Увеличьте значение внутри ljust, если оно еще не очень.

person dheerosaur    schedule 13.09.2010