Understanding the Python %g in string formatting, achieving Java String.format behavior
Understanding the Python %g in string formatting, achieving Java String.format behavior
With the format
method, you can do something like this:
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))
Output:
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
There are two parts to it that might not be so well known.
1. Parametrizing the string formatting
In addition to simple formatting:
>>> {}.format(3.5)
3.5
and formatting with more detailed specification of the result:
>>> {:5.2f}.format(3.5)
3.50
you can use keyword arguments in format
that you can access in the string :
>>> {num:5.2f}.format(num=3.5)
3.50
You can use these also for the format specification itself:
>>> {:5.{deci}f}.format(3.5, deci=3)
3.500
2. The if
expression
In addition to the if
statement there is an if
expression, a.k.a. ternary operator.
So, this expression:
a = 1
b = 2
res = 10 if a < b else 20
is equivalent to this statement:
if a < b:
res = 10
else:
res= 20
Putting both together yields something like this:
{num:7.2{c}}.format(num=num, c=e if num > 1e4 else f)
The formatting that python does is more consistent with Cs printf
style formatting, which also drops trailing zeros for the g
conversion. Since pythons reference implementation is in C, why should it be consistent with Java in this case?
When using the %
operator for string formatting, the relevant documentation is String Formatting Operations, which has some differences to the one you linked to, notably that it allows the #
alternate form for 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.
So in your case:
>>> %#7.2g % 3e9
3.0e+09
This is different from what is allowed by str.format()
, where #
is used to enable prefixes for binary, octal or hexadecimal output (at least in python2, this was changed in python3).