Pulpcode

捕获,搅碎,拼接,吞咽

0%

使用python对齐文本列

最近经常要生成一些分析数据,这些数据看上去就像是文本表格。

     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
# -*- coding:utf-8 -*-

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

比较有趣的是,我使用了函数式编程的风格来实现这个功能(当然,并不是很标准的函数式编程)

将这些函数通过数据流”连”起来,这种感觉就像是通过管道将一系列的化学容器连起来,从初始物品经过一系列的反应,最后产生了需要的东东(比如蓝色沉淀之类的)

Chemistry_Experiment

后记:

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