尝试使用格式说明符打印一个小于1而没有前导零的浮点数。我想出了一些黑客,但我认为有一种方法可以在格式说明符中删除前导零。我在文档中找不到它。
问题
>>> k = .1337
>>> print "%.4f" % k
'0.1337'
哈克
>>> print ("%.4f" % k) [1:]
'.1337'
答案 0 :(得分:30)
这是另一种方式:
>>> ("%.4f" % k).lstrip('0')
'.1337'
它比[1:]
更为通用,因为它也适用于数字> = 1。
但是,这两种方法都没有正确处理负数。在这方面,以下情况更好:
>>> re.sub('0(?=[.])', '', ("%0.4f" % -k))
'-.1337'
不是特别优雅,但现在我想不出更好的方法。
答案 1 :(得分:8)
尽管我喜欢可爱的正则表达式技巧,但我认为直接的功能是最好的方法:
def formatFloat(fmt, val):
ret = fmt % val
if ret.startswith("0."):
return ret[1:]
if ret.startswith("-0."):
return "-" + ret[2:]
return ret
>>> formatFloat("%.4f", .2)
'.2000'
>>> formatFloat("%.4f", -.2)
'-.2000'
>>> formatFloat("%.4f", -100.2)
'-100.2000'
>>> formatFloat("%.4f", 100.2)
'100.2000'
这样做的好处是易于理解,部分原因是startswith
是一个简单的字符串匹配而不是正则表达式。
答案 2 :(得分:6)
一个可行的选项,没有正则表达式,负数大于10
k = -.1337
("%.4f" % k).replace("-0","-").lstrip("0")
答案 3 :(得分:4)
import re
re.sub("^(\-?)0\.", r'\1.', "%.4f" % k)
这很简单,我无法找到一个不起作用的场景。
示例:
>>> import re
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % 0)
'.0000'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % 0.1337)
'.1337'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % 1.337)
'1.3370'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % -0)
'.0000'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % -0.1337)
'-.1337'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % -1.337)
'-1.3370'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % 10.337)
'10.3370'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % -10.337)
'-10.3370'
修改强>: 如果您只考虑数字> -10和< 10以下内容将起作用:
("%.4f", k).replace('0.', '.')
答案 4 :(得分:4)
更倾向于阅读和简单:让我们独立处理标志和数字。如果声明永远不会伤害任何人,那么有点内联。
k = -.1337
"".join( ["-" if k < 0 else "", ("%.4f" % abs(k)).lstrip('0')] )
答案 5 :(得分:4)
使用字符串格式转换为字符串后使用.lstrip()
:
>>> k = .1827412
>>> print ("%.4f"%(k)).lstrip('0')
.1827
>>>
.lstrip()
可用于删除字符串中的任何主要字符:
>>> k = 'bhello'
>>> print k.lstrip('b')
hello
>>> print k.lstrip('bhel')
o
>>> print k.lstrip('bel')
hello
>>>
string.lstrip(s [,chars])
返回删除了前导字符的字符串副本
答案 6 :(得分:4)
您可以使用以下MyFloat
课程代替内置float
课程。
def _remove_leading_zero(value, string):
if 1 > value > -1:
string = string.replace('0', '', 1)
return string
class MyFloat(float):
def __str__(self):
string = super().__str__()
return _remove_leading_zero(self, string)
def __format__(self, format_string):
string = super().__format__(format_string)
return _remove_leading_zero(self, string)
使用此类,您必须使用str.format
函数而不是模数运算符(%
)进行格式化。以下是一些例子:
>>> print(MyFloat(.4444))
.4444
>>> print(MyFloat(-.4444))
-.4444
>>> print('some text {:.3f} some more text',format(MyFloat(.4444)))
some text .444 some more text
>>> print('some text {:+.3f} some more text',format(MyFloat(.4444)))
some text +.444 some more text
如果您还想使%
类的模数运算符(str
)的行为方式相同,那么您必须覆盖__mod__
str
方法1}}通过继承类的类。但它不会像覆盖__format__
类的float
方法一样容易,因为在这种情况下,格式化的浮点数可能出现在结果字符串中的任何位置。
[注意:以上所有代码都是用Python3编写的。 您还必须覆盖Python2中的__unicode__
,还必须更改super
来电。]
P.S。:如果您还想更改__repr__
的{{3}},也可以覆盖类似于__str__
的{{1}}方法。
修改:实际上,您可以使用MyFloat
方法添加新语法来格式化sting。因此,如果你想保持这两种行为,即在需要时显示前导零并且在不需要时不显示前导零。您可以按如下方式创建__format__
类:
MyFloat
使用此课程如下:
class MyFloat(float):
def __format__(self, format_string):
if format_string.endswith('z'): # 'fz' is format sting for floats without leading the zero
format_string = format_string[:-1]
remove_leading_zero = True
else:
remove_leading_zero = False
string = super(MyFloat, self).__format__(format_string)
return _remove_leading_zero(self, string) if remove_leading_zero else string
# `_remove_leading_zero` function is same as in the first example
请注意使用&#39; fz&#39;而不是&#39; f&#39;删除前导零。
此外,上述代码适用于Python2和Python3。
答案 7 :(得分:2)
因为我们只考虑&gt; -1到&lt; 1然后以下编辑将起作用。
import re
re.sub(r"0+\.", ".", %0.4f" % k)
这将保持符号,只删除小数点左边的数字。
答案 8 :(得分:2)
我很惊讶没有人提出更多数学方法来做到这一点:
n = 0.123456789
'.%d' % (n*1e4)
对我来说看起来更好。 :)
但有趣的是你的速度最快。
$ python -mtimeit '".%d" % (0.123456789*1e4)'
1000000 loops, best of 3: 0.809 usec per loop
$ python -mtimeit '("%.4f"%(0.123456789)).lstrip("0")'
1000000 loops, best of 3: 0.209 usec per loop
$ python -mtimeit '("%.4f"%(0.123456789))[1:]'
10000000 loops, best of 3: 0.0723 usec per loop
答案 9 :(得分:1)
Python的标准lib的str.format()可用于生成float值的字符串转换。然后可以操纵该字符串以形成正数或负数的最终结果。
n = -.1234567890
print('{0}'.format('-' if n < 0 else '') + ('{:0.4}'.format(n).split('-')[1 if n < 0 else 0].lstrip('0')))
答案 10 :(得分:0)
当您需要简单的东西并且不需要负数支持时:
f'{k:.4f}'.lstrip('0')
当您需要负数支持时,还有其他解决方案,包括@ nettux443提供的出色正则表达式。
答案 11 :(得分:0)
一个超短(尽管不是很Pythonic)的单行代码,它也处理负数:
k = -.1337
"-"*(k<0)+("%.4f"%abs(k)).lstrip('0')
答案 12 :(得分:0)
问题是打印浮点数时不带前导零。前导零始终位于小数点之前。将打印的浮点数拆分为“ 0.”,然后仅在“。”附近重新加入结果列表,如下所示:
>> flt = -.31415926
-0.31415926
>> '%.4f' % flt # prints leading zero
'-0.3142'
>> '.'.join( ('%.4f' % flt).split('0.')) # removes leading zero
'-。3142'