Context

我在Python 3中将数字作为字符串接收,并希望将它们作为字符串发送,以便保持准确性,以便upstream 服务器可以将数字作为字符串转换为decimal.Decimal而不会损失精度.

[Admins: I have repeatedly searched Stack Overflow and other resources can cannot find anyone asking or answering this specific question.]

Question

How do I use 100 to provide the given floating point format (below)?表明这是不可能的是一个可以接受的答案.

Succinctly put, the format is just to provide at least one decimal place at all times even if that is just a trailing zero, but never to perform any rounding.

我想可能有Formatter class的解决方案,如果有的话,这是可以接受的,但str.format解决方案是更好的.

我很有兴趣知道f-strings是否也能做到这一点.在这种情况下,使用f字符串不是首选的答案,但了解f字符串是否可以提供这种格式会很有趣(而不只是将演示的表达式打包到f字符串中以供执行:这只是将所需的代码移到第二个求值环境中).

Required Format

把数字和int the format must suffix 101 to whole numbers only if they are presented without any decimal places, but preserve exactly any decimal places that are presented, even if that includes trailing zeroes.区分开来

正在考虑的另一种解决方案是strip all trailing decimal places that are zeroes but leave one and only one trailing decimal zero for whole numbers (and of course preserve all non-zero decimal places without rounding).

传入的字符串可以预期为有效的intDecimal.只有小数点而没有小数位的整数的特殊情况是无效的,不会发生(不需要处理"42.").空字符串("")不会出现.

仅配置到大量小数位("{:.28f}".format(1))是不可接受的.

Demonstration

AFAIK这应该是必需的行为.使用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.0
42.0000 => 42.0000
42.34 => 42.34
42.3400 => 42.3400
42.3456 => 42.3456

备择

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

for number in ("42", "4200", "42.0000", "42.34", "42.3400", "42.3456"):
    string = (
        number.rstrip("0")[-1] == "." and number.rstrip("0") + "0"
        or "." not in number and number + ".0"
        or number.rstrip("0")
    )
    print(number, "=>", string)
42 => 42.0
4200 => 4200.0
42.0000 => 42.0
42.34 => 42.34
42.3400 => 42.34
42.3456 => 42.3456

推荐答案

虽然使用字符串操作的现有方法非常好,但如果必须使用str.format,则必须从给定数字的小数位数计算所需的精度,该精度可以从转换为decimal.Decimal后的数字的指数获得.使用max函数确保精度至少为1:

from decimal import Decimal

def format(number):
    n = Decimal(number)
    return '{:.{}f}'.format(n, max(1, -n.as_tuple().exponent))

或者用f弦:

def format(number):
    n = Decimal(number)
    return f'{n:.{max(1, -n.as_tuple().exponent)}f}'

以便:

for number in "42", "42.0000", "42.34", "42.3400", "42.3456":
    print(number, "=>", format(number))

输出:

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

演示:https://ideone.com/9JbLA0

要生成问题中的替代输出,可以首先规格化Decimal对象:

def format(number):
    n = Decimal(number)
    return '{:.{}f}'.format(n, max(1, -n.normalize().as_tuple().exponent))

这将使测试代码输出:

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

演示:https://ideone.com/hbx3Q0

Python相关问答推荐

如何确保Flask应用程序管理面板中的项目具有单击删除功能?

零填充2D数组上的Numpy切片

将C struct 的指针传递给Python中的ioctel

除了Python之外,可以替代bare?

在Python中管理多个OpenGVBO和VAO实例

从今天起的future 12个月内使用Python迭代

DuckDB将蜂巢分区插入拼花文件

Python:在类对象内的字典中更改所有键的索引,而不是仅更改一个键

Pandas 有条件轮班操作

将数据框架与导入的Excel文件一起使用

按顺序合并2个词典列表

如何让程序打印新段落上的每一行?

无法定位元素错误404

如何在python polars中停止otherate(),当使用when()表达式时?

如果条件不满足,我如何获得掩码的第一个索引并获得None?

在ubuntu上安装dlib时出错

无论输入分辨率如何,稳定扩散管道始终输出512 * 512张图像

在Python中计算连续天数

如何杀死一个进程,我的Python可执行文件以sudo启动?

为什么'if x is None:pass'比'x is None'单独使用更快?