使用没有前导或尾随零的 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'