printing - Formatting output python -


i have code print dictionary in format. number of channels can vary, want change format. wonder if can done easy adjustment have? here code:

band3={'channel11': [10812, 2162, 1972], 'channel10': [10787, 2157, 1967], 'channel3': [10612, 2122, 1932], 'channel2': [10589, 2117, 1927], 'channel1': [10564, 2112, 1922], 'channel7': [10712, 2142, 1952], 'channel6': [10687, 2137, 1947], 'channel5': [10662, 2132, 1942], 'channel4': [10637, 2127, 1937], 'channel9': [10762, 2152, 1962], 'channel8': [10737, 2147, 1957], 'channel12': [10837, 2167, 1977]}  table = [[], [], [], []] # can't sort channel names because 'channel11' < 'channel2' channel_numbers = [] 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()  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     in range(len(cell_widths)): #4         cell = column[i]         padded_cell = cell + ' '*(column_widths-len(cell))         table[i].append(padded_cell)    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])))         

here output currently:

       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      

instead of having data listed on 1 long line, want change after every 4 elements next bit of data printed on new line.

       channel 1 channel 2 channel 3 channel 4 uarfcn 10564     10589     10612     10637        dl/ul  2112/1922 2117/1927 2122/1932 2127/1937  rssi   20        0         0         26             channel 5 channel 6 channel 7 channel 8  uarfcn 10662     10687     10712     10737          dl/ul  2112/1922 2117/1927 2122/1932 2127/1937    rssi   32        0         26        0                          channel 9 channel 10 channel 11 channel 12        uarfcn 10762     10787      10812      10837  dl/ul  2132/1942 2137/1947 2142/1952 2147/1957  rssi   0         0          0          15 

edit mar:

names = ["", "uarfcn", "dl/ul", "rssi"] lwidth = max(len(l) l in names) in range(0, len(table[0]), 4):     j, head in enumerate(names):         print(' {0:<{lwidth}} {1}'.format(head, ' '.join(table[j][i:i+4])))     print 

did know str.format() can justifying you? adding <6 formatting string tells format left-adjust text spaces fit in 6 characters: '{0:<6} {1}'. can same rest of table 'columns', including using variable width formatting.

moreover can use descriptive naming in format, plus use sequence indexing form whole row:

table_row = '{label:<{lwidth}} {row[0]:<{cwidth}} {row[1]:<{cwidth}} {row[2]:<{cwidth}} {row[3]:<{cwidth}}' 

to create four-column formatting column width given parameter cwidth. made label width variable well, can later on tinker labels (add more, use verbose labels, etc.) without breaking layout.

next, group data in dictionaries per label easier processing:

labels = ('', 'uarfcn', 'dl/ul', 'rssi') lwidth = max(len(l) l in labels) table = []  channel_numbers = [int(cname[7:]) if cname.startswith('channel') else none cname in band3] if none in channel_numbers:     raise valueerror("channel name doesn't follow pattern") channel_numbers.sort()  cwidth = 0 channel_number in channel_numbers:     channel_data = band2['channel{}'.format(channel_number)]     entry = dict(zip(labels, (         'channel {}'.format(channel_number),         channel_data[0],         '{}/{}'.format(*channel_data[1:3]),         channel_data[3]     )))     cwidth = max(cwidth, max(len(str(v)) v in entry.values()))     table.append(entry) 

now have table data in list dictionary entries; it's easier group them way. next use itertools grouper recipe:

from itertools import izip_longest  def grouper(iterable, n, fillvalue=none):     "collect data fixed-length chunks or blocks"     # grouper('abcdefg', 3, 'x') --> abc def gxx     args = [iter(iterable)] * n     return izip_longest(fillvalue=fillvalue, *args)  # use empty dictionary filler @ end group in grouper(table, 4, dict.fromkeys(labels, '')):     label in labels:         print(table_row.format(label=label, cwidth=cwidth, lwidth=lwidth,             row=[entry[label] entry in group]))     print() 

this outputs (with reconstructed band2 , band3 input):

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

the dict.fromkeys(labels, '') default makes sure if have 1 row fewer 4 entries in table, last column(s) filled empty strings:

       channel 1  channel 2  channel 3  channel 4  uarfcn 10564      10589      10612      10637      dl/ul  2112/1922  2117/1927  2122/1932  2127/1937  rssi   20         0          0          26                 channel 5  channel 6  channel 7  channel 8  uarfcn 10662      10687      10712      10737      dl/ul  2132/1942  2137/1947  2142/1952  2147/1957  rssi   32         0          26         0                  channel 9  channel 10 channel 11            uarfcn 10762      10787      10812                 dl/ul  2152/1962  2157/1967  2162/1972             rssi   0          0          0                     

Comments

Popular posts from this blog

c# - Operator '==' incompatible with operand types 'Guid' and 'Guid' using DynamicExpression.ParseLambda<T, bool> -