我在SE上阅读了很多关于此的讨论,但仍然无法找到合适的。
我想绘制一些不同长度的数字,数字位数相同。
例如,我有:12.345678
,1.2345678
。现在,由于我必须用错误绘制它们,我希望每个都有不同的格式,以便它们是重要的。
所以,我想用可变数量的小数来绘制它们。在我的情况下,绘制23.45678+/-1.23456
是没有意义的,但更好的是23.4+/-1.2
。另一方面,我需要1.234567+/-0.034567
成为1.23+/-0.03
。
所以,让我们说,我想绘制所有固定宽度的数字,总共可以是3位数加上逗号。我应该使用像'%1.1f' %num
这样的东西,但我找不到正确的方法。我怎么能这样做?
答案 0 :(得分:2)
我建议定义一个解释字符串格式化程序的类来提供你想要的东西
在该类中,您确定浮点数的整数部分的长度,并使用它来定义适当的字符串格式
简而言之,如果输入为'{:4.1f}'
(因为小数点分隔符前有两位数),则类会创建格式化程序12.345
;如果输入{:4.2f}
,则创建1.2345
格式化程序(因为在小数点分隔符之前只有一位数)。总数(本例中为4
)作为输入提供
新的格式化程序为:{:nQ}
其中n
是总位数(因此在上面的示例中,您指定{:4Q}
以获得所需的输出。
这是代码:
import math
class IntegerBasedFloat(float):
def __format__(self, spec):
value = float(self)
# apply the following only, if the specifier ends in Q
# otherwise, you maintain the original float format
if spec.endswith('Q'):
# split the provided float into the decimal
# and integer portion (for this math is required):
DEC, INT = math.modf(value)
# determine the length of the integer portion:
LEN = len(str(abs(int(INT))))
# calculate the number of available decimals
# based on the overall length
# the -1 is required because the separator
# requires one digit
DECIMALS = int(spec[-2]) - LEN - 1
if DECIMALS < 0:
print 'Number too large for specified format'
else:
# create the corresponding float formatter
# that can be evaluated as usual:
spec = spec[-2] + '.' + str(DECIMALS) + 'f'
return format(value, spec)
DATA = [12.345, 2.3456, 345.6789]
print '{:4Q}'.format(IntegerBasedFloat(DATA[0]))
print '{:4Q}'.format(IntegerBasedFloat(DATA[1]))
print '{:4Q}'.format(IntegerBasedFloat(DATA[2]))
print 'This is a "custom" float: {:5Q} and a "regular" float: {:5.3f}'.format(IntegerBasedFloat(12.3456),12.3456)
输出应为:
12.3
2.35
346
This is a "custom" float: 12.35 and a "regular" float: 12.346
这个答案的灵感来自:
- splitting a number into the integer and decimal parts in python
- Add custom conversion types for string formatting