了解字符串格式中的 Python %g,实现 Java String.format 行为
Understanding the Python %g in string formatting, achieving Java String.format behavior
在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
嗯?看起来精度 (.2) 参数在 Python 的 %g
中与在 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 行为(本质上是小数点右边的有效数字位数)而不必从头开始重写整个内容?
使用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
它有两个部分可能不太为人所知。
1。参数化字符串格式
除了简单的格式化:
>>> '{}'.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
表达式 a.k.a。 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 的 printf
样式格式更加一致,它也删除了 g
转换的尾随零。既然python的参考实现是用C写的,为什么要和Java在这种情况下保持一致呢?
当使用 %
运算符进行字符串格式化时,相关文档是 String Formatting Operations,它与您链接到的文档有一些不同,特别是它允许 #
替代g
的形式:
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 中更改)。
在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
嗯?看起来精度 (.2) 参数在 Python 的 %g
中与在 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 行为(本质上是小数点右边的有效数字位数)而不必从头开始重写整个内容?
使用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
它有两个部分可能不太为人所知。
1。参数化字符串格式
除了简单的格式化:
>>> '{}'.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
表达式 a.k.a。 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 的 printf
样式格式更加一致,它也删除了 g
转换的尾随零。既然python的参考实现是用C写的,为什么要和Java在这种情况下保持一致呢?
当使用 %
运算符进行字符串格式化时,相关文档是 String Formatting Operations,它与您链接到的文档有一些不同,特别是它允许 #
替代g
的形式:
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 中更改)。