<p>如果让用户传入块大小,则可以使用<a href="https://docs.python.org/2/library/itertools.html#recipes" rel="nofollow">grouper recipe</a>的变体。在</p>
<pre><code>def sprintf(iterable,fmt, n):
args = zip(*[iter(iterable)] * n)
return "".join([fmt % t for t in args])
</code></pre>
<p>输出:</p>
^{pr2}$
<p>当块大小不是列表大小的倍数时,可以使用izip_longest和str.格式但它不允许您在没有错误的情况下指定类型:</p>
<pre><code>from itertools import izip_longest
def sprintf(iterable, fmt, n, fillvalue=""):
args = izip_longest(*[iter(iterable)] * n, fillvalue=fillvalue)
return "".join([fmt.format(*t) for t in args])
</code></pre>
<p>如果您拆分占位符或让用户传递一个iterable占位符,您可以捕获所有潜在的问题。在</p>
<pre><code> def sprintf(iterable, fmt, sep=" "):
obj = object()
args = izip_longest(*[iter(iterable)] * len(fmt), fillvalue=obj)
return "".join(["{sep}".join([f % i for f, i in zip(fmt, t) if i is not obj]).format(sep=sep) + "\n"
for t in args])
</code></pre>
<p>演示:</p>
<pre><code>In [165]: sprintf(li, ["%.2f", "%d", "%.2f", "%2.f"])
Out[165]: '1.00 2 3.00 4\n5.00 6\n'
In [166]: sprintf(li, ["%d", "%d", "%d"])
Out[166]: '1 2 3\n4 5 6\n'
In [167]: sprintf(li, ["%f", "%f", "%.4f"])
Out[167]: '1.000000 2.000000 3.0000\n4.000000 5.000000 6.0000\n'
In [168]: sprintf(li, ["%.2f", "%d", "%.2f", "%2.f"])
Out[168]: '1.00 2 3.00 4\n5.00 6\n'
</code></pre>