使用 str.format 格式化至少 1 位小数的数字,无需四舍五入,也无需添加额外的尾随零

问题描述 投票:0回答:1

背景

我在 Python 3 中接收数字作为字符串,并希望将它们作为字符串传输以保持准确性,以便上游服务器可以将数字字符串转换为

decimal.Decimal
而不会损失准确性。

[管理员:我反复搜索 Stack Overflow 和其他资源,找不到任何人询问或回答这个特定问题。]

问题

如何使用

str.format
提供给定的浮点格式(如下)?表明这是不可能的,这是一个可以接受的答案。

简而言之,该格式只是提供始终至少有一位小数,即使只是尾随零,但绝不执行任何舍入。

我想可能有一个 Formatter class 解决方案,如果可用的话,这是可以接受的,但

str.format
解决方案是首选。

我有兴趣知道 f-strings 是否也能实现这一点。在这种情况下,使用 f-strings 并不是首选的答案,但了解 f-strings 是否可以提供这种格式(而不只是将演示的表达式打包在 f-string 中以供执行)会很有趣:这只是移动所需的代码进入二级评估环境)。

所需格式

为了区分数字和

int
仅当数字不带任何小数位时,格式才必须将
".0"
后缀为整数,但要准确保留所显示的所有小数位,即使其中包含尾随零。

有一种正在考虑的替代解决方案,即去除所有尾随小数位为零,但为整数保留一个且仅一个尾随小数零(当然保留所有非零小数位而不进行四舍五入)

传入的字符串预计是有效的

int
Decimal
。接收只有小数点且没有小数位的整数的特殊情况是无效的,不会发生(无需处理
"42."
)。不会出现空字符串(
""
)。

仅配置大量小数位是不可接受的(

"{:.28f}".format(1)
)。

示范

据我所知,这应该是必需的行为。使用

format
寻找此行为:

for number in ("42", "4200", "42.0000", "42.34", "42.3400", "42.3456"):
    string = "." in number and number or number + ".0"
    print(number, "=>", string)

42 => 42.0
4200 => 4200.00
42.0000 => 42.0000
42.34 => 42.34
42.3400 => 42.3400
42.3456 => 42.3456

替代方案

正在进行中:目前这是不正确的,很快就会改变

这种替代行为也是可以接受的。

for number in ("42", "42.0000", "42.34", "42.3400", "42.3456"):
    stripped = number.rstrip("0").rstrip(".")
    string = "." in stripped and stripped or stripped + ".0"
    print(number, "=>", string)
42 => 42.0
42.0000 => 42.0
42.34 => 42.34
42.3400 => 42.34
42.3456 => 42.3456
python python-3.x decimal string-formatting
1个回答
0
投票

f-string
可能有帮助:

# For whole numbers add .0 if they are presented without any decimal places
fmt_string = "{{:.{}f}}".format(1 if number % format_string = "{{:.{}f}}".format(1 if number % 1 == 0 else 0)
# For Decimal, preserve all decimal places 
fmt_string = "{:." + str(number_str[::-1].find('.') + 1) + "f}"
© www.soinside.com 2019 - 2024. All rights reserved.