使用没有前导或尾随零的 f 字符串将数字转换为字符串?
Number to string conversion with f-string without leading or trailing zeros?
Update: as up to now (2019-09), masking leading or trailing zeros in decimal numbers formatted to string seems to be unsupported in
Python. You will need to use a workaround to get something like '.01'
from the number 0.0101 (assuming 3 decimal places desired).
I would even argue that it's a good thing not to support such a format
since
- I'd consider '0.01' be better in terms of readability than '.01'
- '0.010' carries information (3 digits of precision...) that is lost in '0.01'
If desired anyway, one could use one of the suggestions below. Thank you all for contributing.
问: 我正在寻找一种将浮点数输出为字符串的方法,格式为 without leading/trailing zeros .有没有办法用 '{ }'.format()
或 f-string 来做到这一点?我搜索了互联网,但没有找到任何东西。我只是错过了还是不可能 (Python 3.7)?
我的想法基本上是
some_number = 0.3140
string = f'{some_number:x}' # giving '.314'
给出输出 string '.314'.
。那么有没有 x
可以做到这一点?
当然可以使用 lstrip
/ rstrip
来变通,例如here or similar here:
In [93]: str(0.3140).lstrip('0').rstrip('0')
Out[93]: '.314'
但是只使用一个f-string会更方便。由于我可以将其用于其他格式设置选项,因此可选地调用 strip
需要额外的代码行。
如果你只想从浮点数中去掉 0,你可以使用这个 "hack"
"." + str(0.314).split("0.")[-1]
这绝不是一个优雅的解决方案,但它可以完成工作
此外,如果您也想使用 .format,则不需要另一行,您可以
"." +str(0.314).split("0.")[-1].format('')
如果您想使用format()
,请尝试以下操作。
print("Hello {0}, your balance is {1}.".format("Adam", "0.314".lstrip('0')))
只需在格式化函数中使用lstrip()
,您无需编写额外的代码行。
这是我想出的一个辅助函数,因为无法避免 strip
解决方法:
def dec2string_stripped(num, dec_places=3, strip='right'):
"""
Parameters
----------
num : float or list of float
scalar or list of decimal numbers.
dec_places : int, optional
number of decimal places to return. defaults to 3.
strip : string, optional
what to strip. 'right' (default), 'left' or 'both'.
Returns
-------
list of string.
numbers formatted as strings according to specification (see kwargs).
"""
if not isinstance(num, list): # might be scalar or numpy array
try:
num = list(num)
except TypeError: # input was scalar
num = [num]
if not isinstance(dec_places, int) or int(dec_places) < 1:
raise ValueError(f"kwarg dec_places must be integer > 1 (got {dec_places})")
if strip == 'right':
return [f"{n:.{str(dec_places)}f}".rstrip('0') for n in num]
if strip == 'left':
return [f"{n:.{str(dec_places)}f}".lstrip('0') for n in num]
if strip == 'both':
return [f"{n:.{str(dec_places)}f}".strip('0') for n in num]
raise ValueError(f"kwarg 'strip' must be 'right', 'left' or 'both' (got '{strip}')")
只是在这里提一下...如果您使用 numpy
还有函数 np.format_float_positional()
可以让您完全控制如何将数字显示为字符串和 trim 尾随零...
来自 np.format_float_positional
的文档:
Format a floating-point scalar as a decimal string in positional notation.
Provides control over rounding, trimming and padding. Uses and assumes IEEE >unbiased rounding. Uses the "Dragon4" algorithm.
去掉前导零只是一个简单的检查我们是否正在处理一个以 0 开头的数字
import numpy as np
def format_float(x, trim_leading=True, **kwargs):
s = np.format_float_positional(x, **kwargs)
if trim_leading is True and int(x) == 0 and len(s) > 1:
s = s.replace("0.", ".")
return s
format_float(0.0234001232, trim_leading=True, precision=4)
>>> '.0234'
format_float(0.0234001232, trim_leading=False, precision=4)
>>> '0.0234'
format_float(0.0234001232, precision=8)
>>> '0.02340012'
format_float(12.000558, precision=2, trim="-", fractional=False)
>>> '12'
Update: as up to now (2019-09), masking leading or trailing zeros in decimal numbers formatted to string seems to be unsupported in Python. You will need to use a workaround to get something like '.01' from the number 0.0101 (assuming 3 decimal places desired).
I would even argue that it's a good thing not to support such a format since
- I'd consider '0.01' be better in terms of readability than '.01'
- '0.010' carries information (3 digits of precision...) that is lost in '0.01'
If desired anyway, one could use one of the suggestions below. Thank you all for contributing.
问: 我正在寻找一种将浮点数输出为字符串的方法,格式为 without leading/trailing zeros .有没有办法用 '{ }'.format()
或 f-string 来做到这一点?我搜索了互联网,但没有找到任何东西。我只是错过了还是不可能 (Python 3.7)?
我的想法基本上是
some_number = 0.3140
string = f'{some_number:x}' # giving '.314'
给出输出 string '.314'.
。那么有没有 x
可以做到这一点?
当然可以使用 lstrip
/ rstrip
来变通,例如here or similar here:
In [93]: str(0.3140).lstrip('0').rstrip('0')
Out[93]: '.314'
但是只使用一个f-string会更方便。由于我可以将其用于其他格式设置选项,因此可选地调用 strip
需要额外的代码行。
如果你只想从浮点数中去掉 0,你可以使用这个 "hack"
"." + str(0.314).split("0.")[-1]
这绝不是一个优雅的解决方案,但它可以完成工作
此外,如果您也想使用 .format,则不需要另一行,您可以
"." +str(0.314).split("0.")[-1].format('')
如果您想使用format()
,请尝试以下操作。
print("Hello {0}, your balance is {1}.".format("Adam", "0.314".lstrip('0')))
只需在格式化函数中使用lstrip()
,您无需编写额外的代码行。
这是我想出的一个辅助函数,因为无法避免 strip
解决方法:
def dec2string_stripped(num, dec_places=3, strip='right'):
"""
Parameters
----------
num : float or list of float
scalar or list of decimal numbers.
dec_places : int, optional
number of decimal places to return. defaults to 3.
strip : string, optional
what to strip. 'right' (default), 'left' or 'both'.
Returns
-------
list of string.
numbers formatted as strings according to specification (see kwargs).
"""
if not isinstance(num, list): # might be scalar or numpy array
try:
num = list(num)
except TypeError: # input was scalar
num = [num]
if not isinstance(dec_places, int) or int(dec_places) < 1:
raise ValueError(f"kwarg dec_places must be integer > 1 (got {dec_places})")
if strip == 'right':
return [f"{n:.{str(dec_places)}f}".rstrip('0') for n in num]
if strip == 'left':
return [f"{n:.{str(dec_places)}f}".lstrip('0') for n in num]
if strip == 'both':
return [f"{n:.{str(dec_places)}f}".strip('0') for n in num]
raise ValueError(f"kwarg 'strip' must be 'right', 'left' or 'both' (got '{strip}')")
只是在这里提一下...如果您使用 numpy
还有函数 np.format_float_positional()
可以让您完全控制如何将数字显示为字符串和 trim 尾随零...
来自 np.format_float_positional
的文档:
Format a floating-point scalar as a decimal string in positional notation.
Provides control over rounding, trimming and padding. Uses and assumes IEEE >unbiased rounding. Uses the "Dragon4" algorithm.
去掉前导零只是一个简单的检查我们是否正在处理一个以 0 开头的数字
import numpy as np
def format_float(x, trim_leading=True, **kwargs):
s = np.format_float_positional(x, **kwargs)
if trim_leading is True and int(x) == 0 and len(s) > 1:
s = s.replace("0.", ".")
return s
format_float(0.0234001232, trim_leading=True, precision=4)
>>> '.0234'
format_float(0.0234001232, trim_leading=False, precision=4)
>>> '0.0234'
format_float(0.0234001232, precision=8)
>>> '0.02340012'
format_float(12.000558, precision=2, trim="-", fractional=False)
>>> '12'