Python 零填充特定位置的空白

Python 零填充特定位置的空白,python,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 输出文件:同样的规则适用。对于特定行,每个数字之间仅用一个空格分隔

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

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()在每行的适当位置填充零。我担心它可能会变成一个肮脏的代码,我相信有更好的方法来完成这项任务

欢迎提出任何建议


谢谢大家!

类似这样的内容-但我也认为应该更新,因为您的问题中并非所有内容都清楚:

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)))

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

要计算数字的数量,您可以使用
str.split()
将空格字符作为分隔符,然后您只需获得列表中的条目数。添加您的填充编号应该非常简单


假设
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)))
Re:comment

如果要对齐列,最容易修改第一种方法,因为我们已经在一个点上按列排列了数字。这使得查找列宽变得很容易

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
2
3
4
值是否实际表示数字(即它们可以是任何数字),或者它们是某种符号,在概念上被视为一个字符(即每个数字只能是一个数字)?输入中分隔它们的空格可能不是空格吗?它们在输出文件中的间隔是否重要?@Karl Knechtel:我试图通过更新我原来的问题来解决你的问题。如果您需要更多详细信息,请告诉我。您不需要在最后一行中使用
list
“\n”。请加入(line+'0'*((mLen-len(line))//2)用于res中的line)
@lazyr当然,我的错-只是在发布之前忘了删除它(正在玩迭代器)。谢谢。如果我没有错的话,只要列是个位数,您的解决方案就可以了。但正如我所提到的,他们不必如此。如果输入文件的任何列中都有一个两位数/多位数的数字,那么代码提供的输出就有点混乱,即它们不在(或者说不在开始/结束)同一列中。这样想:由此产生的输出被作为进一步矩阵操作的矩阵。对我来说,这不是一个问题,因为genfromtxt似乎解决了这个问题(至少到目前为止)。所以,我提出它只是为了讨论,谢谢。如果我没有错的话,只要列是个位数,您的解决方案就可以了。但正如我所提到的,他们不必如此。如果输入文件的任何列中都有一个两位数/多位数的数字,那么代码提供的输出就有点混乱,即它们不在(或者说不在开始/结束)同一列中。这样想:由此产生的输出被作为进一步矩阵操作的矩阵。对我来说,这不是一个问题,因为genfromtxt似乎解决了这个问题(至少到目前为止)。因此,我提出它只是为了讨论,请允许我引用您的问题:“输出文件:同样的规则适用。对于特定的行,每个数字与另一行之间仅用一个空格分隔。”。你改变主意了吗?是的,我的错。在看了多数字列的输出后,我不得不改变主意。