如何在Python中规范化字符串的列表列表?

11 投票
8 回答
4775 浏览
提问于 2025-04-17 10:22

我有一个列表,里面又包含了很多列表,这些列表就像是电子表格中的行。每一行可以有任意数量的列,而每个单元格里的数据都是长度不一的字符串。

我想把这些数据整理一下,实际上就是让每一行的列数相同,并且每一列的数据宽度也要一致,如果不够的话就用空格填充。例如,给定以下输入:

(
 ("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 ...)

示例:http://ideone.com/4d0DE

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

撰写回答