如何在Python中规范化字符串的列表列表?
我有一个列表,里面又包含了很多列表,这些列表就像是电子表格中的行。每一行可以有任意数量的列,而每个单元格里的数据都是长度不一的字符串。
我想把这些数据整理一下,实际上就是让每一行的列数相同,并且每一列的数据宽度也要一致,如果不够的话就用空格填充。例如,给定以下输入:
(
("row a", "a1","a2","a3"),
("another row", "b1"),
("c", "x", "y", "a long string")
)
我希望数据看起来像这样:
(
("row a ", "a1", "a2", "a3 "),
("another row", "b1", " ", " "),
("c ", "x ", "y ", "a long string")
)
那么,针对Python 2.6或更高版本,有什么好的解决方案吗?需要说明的是:我并不是想要简单地美化这个列表,而是希望得到一个新的列表(或者元组的元组),里面的值已经用空格填充好了。
8 个回答
2
首先,定义一个填充函数:
def padder(lst, pad_by):
lengths = [len(x) for x in lst]
max_len = max(lengths)
return (x + pad_by * (max_len - length) for x, length in zip(lst, lengths))
然后用 ''
将每个条目填充到相同的长度:
a = # your list of list of string
a_padded = padder(a, ('',))
接着,将这个列表的列表进行转置,这样我们就可以逐列处理数据了。
a_tr = zip(*a_padded)
对于每一行,我们找到字符串的最大长度,然后将其填充到指定的长度。
a_tr_strpadded = (padder(x, ' ') for x in a_tr)
最后,我们再进行一次转置,评估结果。
a_strpadded = zip(*a_tr_strpadded)
return [list(x) for x in a_strpadded]
如果你想要一个元组的元组,而不是列表的列表,可以使用 tuple(tuple(x) for ...)
。
7
这是我想到的:
import itertools
def pad_rows(strs):
for col in itertools.izip_longest(*strs, fillvalue=""):
longest = max(map(len, col))
yield map(lambda x: x.ljust(longest), col)
def pad_strings(strs):
return itertools.izip(*pad_rows(strs))
然后这样调用它:
print tuple(pad_strings(x))
得到的结果是:
(('row a ', 'a1', 'a2', 'a3 '),
('another row', 'b1', ' ', ' '),
('c ', 'x ', 'y ', 'a long string'))
7
首先,我们来看一下你的输入数据:
>>> d = (
("row a", "a1","a2","a3"),
("another row", "b1"),
("c", "x", "y", "a long string")
)
接下来,进行第一次遍历,找出每一列的最大宽度:
>>> col_size = {}
>>> for row in d:
for i, col in enumerate(row):
col_size[i] = max(col_size.get(i, 0), len(col))
>>> ncols = len(col_size)
然后,再进行第二次遍历,把每一列填充到需要的宽度:
>>> result = []
>>> for row in d:
row = list(row) + [''] * (ncols - len(row))
for i, col in enumerate(row):
row[i] = col.ljust(col_size[i])
result.append(row)
这样就能得到我们想要的结果:
>>> from pprint import pprint
>>> pprint(result)
[['row a ', 'a1', 'a2', 'a3 '],
['another row', 'b1', ' ', ' '],
['c ', 'x ', 'y ', 'a long string']]
为了方便,我们可以把这些步骤合并成一个函数:
def align(array):
col_size = {}
for row in array:
for i, col in enumerate(row):
col_size[i] = max(col_size.get(i, 0), len(col))
ncols = len(col_size)
result = []
for row in array:
row = list(row) + [''] * (ncols - len(row))
for i, col in enumerate(row):
row[i] = col.ljust(col_size[i])
result.append(row)
return result