2

有没有办法将“空”数字类型传递给数字格式说明符并让它打印与该说明符关联的空格?

IE。

n = "Scientific:"
v = 123.321
strfmt = "%5.4E"
output = "%s|"+strfmt+"|"
print output % (n, v)

>   Scientific:|1.2332E+02|

v = EMPTY
print output % (n, v)

>   Scientific:|          |

最终目标是在循环时不自适应地改变格式字符串来处理不完整的行

perline = 3
n = ["1st:","2nd:","3rd:","4th:","5th:","6th:"]
v = [1.0, 2.0, 3.0, 4.0]

strfmt = "%5.4E"
output = ("%s|"+strfmt+"|  ")*perline+"\n"

for args in map(EMPTY,*[iter(n),iter(v)]*perline):
    print output % args

>   1st:|1.0000E+00|  2nd:|2.0000E+00|  3rd:|3.0000E+00|
>   4th:|4.0000E+00|  5th:|          |  6th:|          |

为了执行上面的代码,我用 None 替换了 EMPTY 虽然当你将 None 传递给格式字符串时会出错

4

6 回答 6

0

仅使用数字格式将无法做到这一点。你需要一些逻辑:

strfmt = "%5.4E"
v = None

if v in [None, '']:
  output = "%s|          |"
else:
  output = "%s|"+strfmt+"|"
于 2012-02-13T18:59:42.823 回答
0

一种选择是用 替换数字格式,然后在output替换%s元组中创建正确的数字输出或空格,具体取决于v

>>> v = 123.321
>>> "%s|%s|" % (n, "%5.4E" % v if v is not None else " "*10)
'Scientific:|1.2332E+02|'
>>> v = None
>>> "%s|%s|" % (n, "%5.4E" % v if v is not None else " "*10)
'Scientific:|          |'

你可以用一个简单的闭包使它更实用:

def make_default_blank_formatter(format, default):
    def default_blank_formatter(v):
        return format % v if v is not None else default
    return default_blank_formatter

scientific_formatter = make_default_blank_formatter("%5.4E", " "*10)

>>> v = 123.321
>>> "%s|%s|" % (n, scientific_formatter(v))
'Scientific:|1.2332E+02|'
>>> v = None
>>> "%s|%s|" % (n, scientific_formatter(v))
'Scientific:|          |'

编辑:这是您如何重新编写打印代码以使用它:

perline = 3
n = ["1st:","2nd:","3rd:","4th:","5th:","6th:"]
v = [1.0, 2.0, 3.0, 4.0, None, None]

strfmt = "%5.4E"
output = ("%s|%s|  ")*perline

for args in zip(*[iter(n),iter(map(scientific_formatter, v))]*perline):
    print output % args
于 2012-02-13T19:00:07.587 回答
0

简短的回答:对于一个n位置宽的字段, '%​<em>n​s' % '' 就可以了。也就是说, to'%15s' % ''将打印 15 个空格。

长答案:当您在格式说明符中指定宽度时,第一个数字是整个字段的最小宽度。"%5.4E"但是,将占据 5 个以上的位置,因为只有指数已经占据了 3 个位置。

指定类似的东西"%12.4E"并获得一致的结果。对于缺失值,指定"%12s"并传递一个空字符串(不是None)而不是值。

于 2012-02-13T19:03:52.593 回答
0

您可以使用itertools.izip_longest和 中的项目配对,nv用空字符串填充缺失值。

要为 中的项目获得正确的格式v,您可以使用 预格式化浮点数strfmt,并使用类似的东西

output = "%s|%10s|  "

加入 和 中的n项目v。通过这种方式,其中的项目v现在都是字符串,包括空字符串,而不是浮点数和空字符串的混合。


import itertools

perline = 3
n = ["1st:", "2nd:", "3rd:", "4th:", "5th:", "6th:"]
v = [1.0, 2.0, 3.0, 4.0]

strfmt = "%5.4E"
v = (strfmt % val for val in v)
output = "%s|%10s|  "

pairs = itertools.izip_longest(n, v, fillvalue = '')
items = (output % (place, val) for place, val in pairs)
for row in zip(*[items]*perline):
    print(''.join(row))

产量

1st:|1.0000E+00|  2nd:|2.0000E+00|  3rd:|3.0000E+00|  
4th:|4.0000E+00|  5th:|          |  6th:|          |  
于 2012-02-13T19:37:19.857 回答
0

如上所述,只需在打印之前将您的数字转换为字符串,并用相等长度的空字符串替换丢失的数字。这实际上可以写得很紧凑,但是我永远不会在严肃的代码中使用它:

from itertools import izip_longest, groupby, chain

perline = 3
n = ["1st:","2nd:","3rd:","4th:","5th:","6th:"]
v = [1.0, 2.0, 3.0, 4.0]

strfmt = "%5.4E"
output = ("%s|%s|  ")*perline

for _, args in groupby(enumerate(chain(*izip_longest(n, (strfmt % x for x in v),
                                                     fillvalue = ' '*len(strfmt % 0)))),
                       lambda (i, v): i/perline/2):
    print output % zip(*args)[1]

最后一个循环的更具可读性和可靠性的版本:

l = ()
for pair in izip_longest(n, (strfmt % x for x in v),
                         fillvalue = ' '*len(strfmt % 0)):
    l += pair
    if len(l) == perline*2:
        print output % l
        l = ()
于 2012-02-13T19:44:46.320 回答
0

查看响应后,您似乎无法将任何内容传递给数字格式说明符以使其打印与其关联的空白区域。

有很多方法可以解决这个问题,如下所示。我个人喜欢 Unutbu 的部分回答。我认为我最终会这样做的方式是在开始时创建两个格式说明符并使用 Blender 建议的逻辑。

于 2012-02-15T20:19:53.753 回答