零填充特定位置的空白区域

时间:2011-06-10 05:35:37

标签: python

我有一个小问题。我有一个以下格式的文件:

1 2 
1 2 3
1 2
1 2 3 4
2 4

代码中的值实际上代表数字(不一定是单个数字),但它们可以是任何数字,也可以是浮点值。

输入文件:对于特定行,每个数字由一个空格分隔开(分隔符不能是空格以外的任何其他内容)。

我的任务:我想零填充空白区域,使其看起来像这样,即填充空白区域,使其具有漂亮的矩阵外观格式:

1 2 0 0
1 2 3 0
1 2 0 0
1 2 3 4
2 4 0 0

输出文件:适用相同的规则。对于特定行,每个数字仅由一个空格分隔。

使用的语言:Python(或者可能是Shell,如果可能的话)

我知道有一个名为zfill的函数,但我认为这对我没有多大帮助。

我的解决方案:使用len和max函数查找每行的(最大长度/ 2)。然后,使用split(),在每行的适当位置填充零。我担心它可能变成一个脏代码,我相信有更好的方法来完成这个任务。

欢迎任何建议。

谢谢!

3 个答案:

答案 0 :(得分:2)

假设myfile是打开的文件。我们使用itertools中的izip_longest迭代输入文件的列,填入"0"以查找缺失值:

[('1', '1', '1', '1', '2'),  ('2', '2', '2', '2', '4'),      
 ('0', '3', '0', '3', '0'), ('0', '0', '0', '4', '0')]

然后我们再次压缩此输出以恢复填充了零的行。这是代码:

from itertools import izip_longest

rows = [line.split() for line in myfile]            # Read
rows = zip(*izip_longest(*rows, fillvalue="0"))     # Add zeroes
print "\n".join(" ".join(row) for row in rows)      # Write

编辑:以上(imho优雅)解决方案比天真的方法稍慢(8.55 usec与7.08 usec):

rows = [line.split() for line in myfile]
maxlen = max(len(x) for x in rows)
for row in rows:
    print " ".join(row + ["0"] * (maxlen - len(row)))

回复:评论

如果你想对齐列,最容易修改第一种方法,因为我们已经在一个点上按列排列了数字。这样可以轻松找到列宽。

from itertools import izip_longest

rows = [line.split() for line in myfile]
columns = list(izip_longest(*rows, fillvalue="0"))
column_width = [max(len(num) for num in col) for col in columns]

# We make a template of the form "{0:>a} {1:>b} {2:>c} ...",
# where a, b, c, ... are the column widths:
column_template = "{{{0}:>{1}s}}"
row_template = " ".join(column_template.format(i, n) for
    i, n in enumerate(column_width))

print "\n".join(row_template.format(*row) for row in zip(*columns))

答案 1 :(得分:1)

您可以随时阅读每一行并计算您拥有的数字。然后,您可以将此行写入新的临时文件并在之后附加填充,如果需要,您可以使用此临时文件覆盖原始文件。

要计算您可以使用str.split()以空白字符作为分隔符的数字的数量,那么您只需获取列表中的条目数。附加填写号应该非常简单。

More documentation on str.split()

答案 2 :(得分:0)

这样的事情 - 但我也相信它应该更新,因为你的问题并非一切都清楚:

tst="""
       1 2
       1 2 3
       1 2
       1 2 3 4
       2 4
    """
res = [line for line in tst.split('\n') if line != '']
mLen = max(len(line) for line in res)   
print '\n'.join(list((line + ' 0' * ((mLen - len(line))//2) for line in res)))