最近经常要生成一些分析数据,这些数据看上去就像是文本表格。
apple pear banana orange
dog cat rabbit monkey
sky moon grubby tod
但是这些数据没有对齐,对于我这样的强迫症很是受不了。
所以我用python写了如下代码:
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
def loaddata(fname): ''' 从指定文件读取数据 ''' with open(fname) as f: return [stripwords(line) for line in f]
def wordsmaxlen(words): ''' 返回一个单词列表中的单词的最大长度 ''' return max([len(word) for word in words])
def stripwords(line): ''' 将一行数据分割为单词 ''' return [word.strip() for word in line.split()]
def transpose_wordsmatrix(wordsmatrix): ''' 转置一个单词矩阵 ''' return map(list, zip(*wordsmatrix))
def colsmaxlen(wordsmatrix): ''' 返回一个列表,获得每一列的最大长度… ''' return [wordsmaxlen(col) for col in (wordsmatrix)]
def appendspace(word, width): ''' 返回一个字符串,为字符串尾部添加空字符,使其长度达到width ''' return word+''.join([' ' for i in range(width - len(word))])
def alignment_rows(w): ''' 从标准输出流中,输出对齐结果,w为单词间距 ''' import sys wordsmatrix = loaddata('data') transwordsmatrix = transpose_wordsmatrix(wordsmatrix) formats = colsmaxlen(transwordsmatrix) for col in wordsmatrix: words = [appendspace(word,formats[i] + w) for i,word in enumerate(col)] line = ''.join(words) sys.stdout.write(line + '\n')
if __name__ == '__main__': print '' alignment_rows(2)
|
输出结果:
apple pear banana orange
dog cat rabbit monkey
sky moon grubby tod
比较有趣的是,我使用了函数式编程的风格来实现这个功能(当然,并不是很标准的函数式编程)
将这些函数通过数据流”连”起来,这种感觉就像是通过管道将一系列的化学容器连起来,从初始物品经过一系列的反应,最后产生了需要的东东(比如蓝色沉淀之类的)

后记:
- 这段代码有两个明显的问题:1.它无法处理每列“单词数”不相同的文本,2.作为每行的最后一个单词,是没有必要为其填充空字符的。
- appendspace函数中用来生成n个空格的实现应该有更好的方式,我没想到。
- 个人感觉用
perl
或者awk
能写出更有创造力的代码,毕竟它们很擅长操作文本。