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
Post a Comment