表格格式化,打印行名称

3

我有一个字典想要格式化成表格:

band3 = \
{'channel1': [10564, 2112, 1922],
 'channel10': [10787, 2157, 1967],
 'channel11': [10812, 2162, 1972],
 'channel12': [10837, 2167, 1977],
 'channel2': [10589, 2117, 1927],
 'channel3': [10612, 2122, 1932],
 'channel4': [10637, 2127, 1937],
 'channel5': [10662, 2132, 1942],
 'channel6': [10687, 2137, 1947],
 'channel7': [10712, 2142, 1952],
 'channel8': [10737, 2147, 1957],
 'channel9': [10762, 2152, 1962]}

我是这样做的:

table = [[], [], [], []]
# can't just sort the channel names because 'channel11' < 'channel2'
channel_numbers = []
for channel_name in band3.keys():
    if channel_name.startswith('channel'):
        channel_number = int(channel_name[7:])
        channel_numbers.append(channel_number)
    else:
        raise ValueError("channel name doesn't follow pattern")
channel_numbers.sort()

for channel_number in channel_numbers:
    channel_data = band2['channel%d' % channel_number]
    column =[
              'Channel %d' % channel_number,
               str(channel_data[0]),
               '%s/%s' % (channel_data[1], channel_data[2]),
               str(channel_data[3])
            ]
    cell_widths = map(len, column) #9 5 2 9
    column_widths = max(cell_widths) # 9 or 10
    for i in range(len(cell_widths)): #4
        cell = column[i]
        padded_cell = cell + ' '*(column_widths-len(cell))
        table[i].append(padded_cell)
for line in table:
    print('  '.join(line))

这将会得到:
Channel 1  Channel 2  Channel 3  Channel 4  Channel 5  Channel 6  Channel 7  Channel 8  Channel 9  Channel 10  Channel 11  Channel 12
10564      10589      10612      10637      10662      10687      10712      10737      10762      10787       10812       10837     
2112/1922  2117/1927  2122/1932  2127/1937  2132/1942  2137/1947  2142/1952  2147/1957  2152/1962  2157/1967   2162/1972   2167/1977 
20         0          0          26         32         0          26         0          0          0           0           15       

现在我想给行命名:

       Channel 1  Channel 2  Channel 3  Channel 4  Channel 5  Channel 6  Channel 7  Channel 8  Channel 9  Channel 10  Channel 11  Channel 12
UARFCN 10564      10589      10612      10637      10662      10687      10712      10737      10762      10787       10812       10837     
DL/UL  2112/1922  2117/1927  2122/1932  2127/1937  2132/1942  2137/1947  2142/1952  2147/1957  2152/1962  2157/1967   2162/1972   2167/1977 
RSSI   20         0          0          26         32         0          26         0          0          0           0           15        

这很容易,我将打印循环更改为:

print "      ",
print('  '.join(table[0])) 
print "UARFCN",
print('  '.join(table[1])) 
print "DL/UL ",
print('  '.join(table[2])) 
print "RSSI  ",
print('  '.join(table[3])) 

然而我想知道一些更好的方法来打印这些列名。如上所述,我可以通过填充计算来详细说明,但我想知道是否有更简单、干净的方法。
编辑:格式化尝试:
print('{0:6s}  {1}'.format("", ' '.join(table[0])))   
print('{0:2s}  {1}'.format("UARFCN", ' '.join(table[1])))   
print('{0:6s}  {1}'.format("DL/UL", ' '.join(table[2])))   
print('{0:6s}  {1}'.format("RSSI", ' '.join(table[3]))) 

编辑:另一种方法

print('{0} {1}'.format("".ljust(6), ' '.join(table[0])))   
print('{0} {1}'.format("UARFCN".ljust(6), ' '.join(table[1])))   
print('{0} {1}'.format("DL/UL".ljust(6), ' '.join(table[2])))   
print('{0} {1}'.format("RSSI".ljust(6), ' '.join(table[3])))  

有改进建议吗?


1
请查看格式 - Elazar
@Elazar 我已经尝试进行编辑,但我相信有更好的格式方式,而不是硬编码6等内容。 - Paul
你可以定义 formatstr = '{0:6s} {1}' 然后使用它。 - Otaia
除了那个多余的2,这个还不错。有没有一些固定宽度参数可以用于每个字符串,并进行左填充调整?/谷歌。 - Paul
为什么是2?看起来应该也是6。 - Otaia
我不确定,那似乎就是它的工作方式。我在那里放了2个以使其正确格式化。我以前没有使用过格式。 - Paul
2个回答

2

像许多Python任务一样,通过导入神奇的模块可以实现更加优雅的代码。在这种情况下,该模块称为prettytable

以下是一些可行的代码:

from prettytable import PrettyTable

band3 = \
{'channel1': [10564, 2112, 1922],
 'channel10': [10787, 2157, 1967],
 'channel11': [10812, 2162, 1972],
 'channel12': [10837, 2167, 1977],
 'channel2': [10589, 2117, 1927],
 'channel3': [10612, 2122, 1932],
 'channel4': [10637, 2127, 1937],
 'channel5': [10662, 2132, 1942],
 'channel6': [10687, 2137, 1947],
 'channel7': [10712, 2142, 1952],
 'channel8': [10737, 2147, 1957],
 'channel9': [10762, 2152, 1962]}

band3_new = {}
for key in band3.keys():
    band3_new[ int( key.split('channel')[1] ) ] = band3[key]

x = PrettyTable()
x.add_column("", ["UARFCN", "DL/UL"])

for channel in band3_new.keys():
    x.add_column("channel " + str(channel), [band3_new[channel][0], str(band3_new[channel][1]) + "/" + str(band3_new[channel][2]) ] )

print x

并且它的输出:

+--------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+------------+------------+------------+
|        | channel 1 | channel 2 | channel 3 | channel 4 | channel 5 | channel 6 | channel 7 | channel 8 | channel 9 | channel 10 | channel 11 | channel 12 |
+--------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+------------+------------+------------+
| UARFCN |   10564   |   10589   |   10612   |   10637   |   10662   |   10687   |   10712   |   10737   |   10762   |   10787    |   10812    |   10837    |
| DL/UL  | 2112/1922 | 2117/1927 | 2122/1932 | 2127/1937 | 2132/1942 | 2137/1947 | 2142/1952 | 2147/1957 | 2152/1962 | 2157/1967  | 2162/1972  | 2167/1977  |
+--------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+------------+------------+------------+

我无法确定你从哪里获取RSSI行的值。


非常漂亮的表格!抱歉我放错了字典,每个列表中的第四个元素是rssi值。 - Paul

0

我猜这会在打印时有所帮助,如果您不介意的话,顺序可以调整一下:

band3 = \
{'channel1': [10564, 2112, 1922],
...
 'channel9': [10762, 2152, 1962]}

types = ['','UARFCN','DL/UL','RSSI']

# ASSUME THE DICTIONARY VALUES ARE EQUAL IN LENGTH
li1 = [types[0]]+band3.keys() # the stuff on the side
li2 = zip(types[1:],*band3.values()) # the main data
li3 = zip(li1,*li2)
for i,x in enumerate(li3):
    x = map(str, x)
    li3[i] = [a.ljust(b) for b in (max(map(len,x)),) for a in x]

final = zip(*li3)
for i in final:
    print ' '.join(i)

输出:

       channel3 channel2 channel1 channel7 channel6 channel5 channel4 channel9 channel8 channel12 channel11 channel10
UARFCN 10612    10589    10564    10712    10687    10662    10637    10762    10737    10837     10812     10787    
DL/UL  2122     2117     2112     2142     2137     2132     2127     2152     2147     2167      2162      2157     
RSSI   1932     1927     1922     1952     1947     1942     1937     1962     1957     1977      1972      1967     

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接