我有一个小问题。我有一个以下格式的文件:
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(),在每行的适当位置填充零。我担心它可能变成一个脏代码,我相信有更好的方法来完成这个任务。
欢迎任何建议。
谢谢!
答案 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()
以空白字符作为分隔符的数字的数量,那么您只需获取列表中的条目数。附加填写号应该非常简单。
答案 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)))