Line up columns of numbers (print output in table format)
我有以下格式保存的数据(数字)(示例):
1 2 3 4 | 234 127 34 23 45567 23 12 4 4 45 23456 2 1 444 567 ... |
是否有任何python方法来排列数字并将它们作为
1 2 3 | 234 127 34 23 45567 23 12 4 4 45 23456 2 1 444 567 |
(我无法预测列大小)。
这是一个简单的自包含示例,演示如何格式化可变列宽:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | data = '''\ 234 127 34 23 45567 23 12 4 4 45 23456 2 1 444 567''' # Split input data by row and then on spaces rows = [ line.strip().split(' ') for line in data.split(' ') ] # Reorganize data by columns cols = zip(*rows) # Compute column widths by taking maximum length of values per column col_widths = [ max(len(value) for value in col) for col in cols ] # Create a suitable format string format = ' '.join(['%%%ds' % width for width in col_widths ]) # Print each row using the computed format for row in rows: print format % tuple(row) |
哪个输出:
1
2
3 234 127 34 23 45567
23 12 4 4 45
23456 2 1 444 567
你需要一些方法来找到列大小,
也许通过读取所有数据并找到最大宽度。
1 2 3 4 5 | >>> line='234 127 34 23 45567' >>> line.split() ['234', '127', '34', '23', '45567'] >>> max(map(len, line.split())) 5 |
重复所有行,找到列大小(例如,5)。
使用
1 2 3 4 | >>> colsize = 5 >>> ' '.join(('%*s' % (colsize, i) for i in line.split())) ' 234 127 34 23 45567' >>> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #!/usr/bin/env python class ALIGN: LEFT, RIGHT = '-', '' class Column(list): def __init__(self, name, data, align=ALIGN.RIGHT): list.__init__(self, data) self.name = name width = max(len(str(x)) for x in data + [name]) self.format = ' %%%s%ds ' % (align, width) class Table: def __init__(self, *columns): self.columns = columns self.length = max(len(x) for x in columns) def get_row(self, i=None): for x in self.columns: if i is None: yield x.format % x.name else: yield x.format % x[i] def get_rows(self): yield ' '.join(self.get_row(None)) for i in range(0, self.length): yield ' '.join(self.get_row(i)) def __str__(self): return ' '.join(self.get_rows()) |
对于你的例子:
1 2 3 4 5 6 7 8 | if __name__ == '__main__': print Table( Column("", [234, 32, 23456]), Column("", [127, 12, 2]), Column("", [34, 4, 1]), Column("", [23, 4, 444]), Column("", [45567, 45, 567]) ) |
它会产生:
1 2 3 | 234 127 34 23 45567 32 12 4 4 45 23456 2 1 444 567 |
改编自http://code.activestate.com/recipes/577202-render-tables-for-text-interface/
1 2 3 | >>> rows ="""234 127 34 23 45567 ... 23 12 4 4 45 ... 23456 2 1 444 567""" |
首先将行转换为2d数组(列表列表)
1 2 | >>> arr=[x.split() for x in rows.split(" ")] |
现在计算每个字段需要适应的空间
1 | >>> widths = [max(map(len,(f[i] for f in tab))) for i in range(len(arr[0]))] |
并填充每个元素以适应该空间
1 2 | >>> [[k.rjust(widths[i]) for i,k in enumerate(j)] for j in arr] [[' 234', '127', '34', ' 23', '45567'], [' 23', ' 12', ' 4', ' 4', ' 45'], ['23456', ' 2', ' 1', '444', ' 567']] |
最后将数组加入一个字符串
1 2 3 4 5 | >>> print" ".join(" ".join(k.rjust(widths[i]) for i,k in enumerate(j)) for j in arr) 234 127 34 23 45567 23 12 4 4 45 23456 2 1 444 567 |
d前面的整数是整数在前一个之后开始的列
数字,所以你可以排队,但你认为合适
必要时重复
试试这个很好的文档示例http://code.activestate.com/recipes/267662-table-indentation/
Kevin Jacobs的答案被修改为允许每行上有可变数量的整数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | def align(data, delimiter = '\t', is_left_align = True): rows = [row.strip().split(delimiter) for row in data.split(' ')] cols = map(lambda *row: [str(field) or '' for field in row], *rows) widths = [max(len(field) for field in col) for col in cols] format = ['%%%s%ds' % ('-' if is_left_align else '', width) for width in widths] return ' '.join([delimiter.join(format[:len(row)]) % tuple(row) for row in rows]) data = '''\ 234 127 34 23 45567 23 12 4 4 45 23456 2 1 444 567''' print(align(data, ' ', False)) |