理解字符串格式中的Python%g,实现Java string.format行为

2024-03-28 06:29:18 发布

您现在位置:Python中文网/ 问答频道 /正文

在Java中:

String test1 = String.format("%7.2g", 3e9);
System.out.println(test1);

打印3.0e+09

在Python2.7中,如果我运行以下代码

for num in [3e9, 3.1e9, 3.01e9, 3e2, 3.1e2, 3.01e2]:
   print '%7.2g %7.2f %7.2e' % (num, num, num)

我明白了

  3e+09 3000000000.00 3.00e+09
3.1e+09 3100000000.00 3.10e+09
  3e+09 3010000000.00 3.01e+09
  3e+02  300.00 3.00e+02
3.1e+02  310.00 3.10e+02
  3e+02  301.00 3.01e+02

嗯?看起来,在Python的%g中,precision(.2)参数的处理方式与在Python的%f、Python的%e或Java的%g中完全不同。这里是doc(我的重点):

General format. For a given precision p >= 1, this rounds the number to p significant digits and then formats the result in either fixed-point format or in scientific notation, depending on its magnitude.

The precise rules are as follows: suppose that the result formatted with presentation type 'e' and precision p-1 would have exponent exp. Then if -4 <= exp < p, the number is formatted with presentation type 'f' and precision p-1-exp. Otherwise, the number is formatted with presentation type 'e' and precision p-1. In both cases insignificant trailing zeros are removed from the significand, and the decimal point is also removed if there are no remaining digits following it.

Positive and negative infinity, positive and negative zero, and nans, are formatted as inf, -inf, 0, -0 and nan respectively, regardless of the precision.

A precision of 0 is treated as equivalent to a precision of 1. The default precision is 6.

世界贸易基金会?有什么方法可以防止那些尾随的零被删除吗?字符串格式的整个要点是实现某种一致性,例如文本对齐。

有没有什么方法可以让Java行为(本质上是小数点右边的有效位数)不必从头重写整个过程?


Tags: andtheinformatnumberisastype
2条回答

使用format方法,您可以执行以下操作:

for num in [3e9, 3.1e9, 3.01e9, 3e2, 3.1e2, 3.01e2]:
    print ('{n:7.2{c}} {n:7.2f} {n:7.2e}'.format(n=num, c='e' if num > 1e4 else 'f'))

输出:

3.00e+09 3000000000.00 3.00e+09
3.10e+09 3100000000.00 3.10e+09
3.01e+09 3010000000.00 3.01e+09
 300.00  300.00 3.00e+02
 310.00  310.00 3.10e+02
 301.00  301.00 3.01e+02

它有两个部分可能不太为人所知。

一。参数化字符串格式

除了简单的格式:

>>> '{}'.format(3.5)
'3.5'

以及更详细地说明结果的格式:

>>> '{:5.2f}'.format(3.5)
' 3.50'

您可以在format中使用关键字参数,您可以在字符串中访问这些参数:

>>> '{num:5.2f}'.format(num=3.5)
' 3.50'

您也可以将其用于格式规范本身:

>>> '{:5.{deci}f}'.format(3.5, deci=3)
'3.500'

2。if表达式

除了if语句之外,还有一个if表达式,也就是ternary operator

所以,这个表达式:

a = 1
b = 2
res = 10 if a < b else 20

相当于这句话:

if a < b:
    res = 10
else:
    res= 20

把两者放在一起会产生如下结果:

'{num:7.2{c}}'.format(num=num, c='e' if num > 1e4 else 'f')

python所做的格式化与C的^{}样式的格式化更为一致,后者还为g转换删除尾随的零。既然python的引用实现是用C语言编写的,那么在这种情况下为什么要与Java保持一致呢?

当使用%运算符进行字符串格式设置时,相关文档是String Formatting Operations,这与您链接到的文档有一些不同,特别是它允许#的替代格式:

The alternate form causes the result to always contain a decimal point, and trailing zeroes are not removed as they would otherwise be.

The precision determines the number of significant digits before and after the decimal point and defaults to 6.

所以在你的情况下:

>>> "%#7.2g" % 3e9
3.0e+09

这与str.format()所允许的不同,其中#用于启用二进制、八进制或十六进制输出的前缀(至少在python2中,这在python3中已更改)。

相关问题 更多 >