更改默认浮动打印格式

Aki*_*oss 14 python floating-point string-formatting python-3.x

我有一些列表和更复杂的结构包含浮点数.打印时,我看到有很多十进制数字的浮点数,但是在打印时,我不需要全部.所以我想在打印浮点数时定义自定义格式(例如2或3位小数).

我需要使用浮点数而不是十进制数.此外,我不允许截断/圆形浮动.

有没有办法改变默认行为?

Don*_*ner 9

像Ignacio说,你不允许使用monkeypatch C类型.

但是,如果你非常紧迫,并且你知道一些C,你可以自己修改Python解释器源代码,然后将其重新编译成自定义解决方案.一旦我修改了列表的标准行为之一,它只是一种中度的痛苦.

我建议你找到一个更好的解决方案,比如用"%0.2f"printf表示法打印浮点数:

for item in mylist:
    print '%0.2f' % item,
Run Code Online (Sandbox Code Playgroud)

要么

print " ".join('%0.2f' % item for item in mylist)
Run Code Online (Sandbox Code Playgroud)

  • 问题是我在列表中浮动,当我打印(列表)时,我无法控制它。(这也适用于其他对象,顺便说一句)。修改源代码是可行的,因为我知道 C,但不是我想的那样。谢谢。 (3认同)

Ano*_*ous 8

这并不能回答嵌套在其他结构中的浮点数的更普遍的问题,但如果您只需要在列表甚至类似数组的嵌套列表中打印浮点数,请考虑使用numpy.

例如,

import numpy as np
np.set_printoptions(precision=3, suppress=False)
list_ = [[1.5398, 2.456, 3.0], 
         [-8.397, 2.69, -2.0]]
print(np.array(list_))
Run Code Online (Sandbox Code Playgroud)

给出

[[ 1.54   2.456  3.   ]
 [-8.397  2.69  -2.   ]]
Run Code Online (Sandbox Code Playgroud)


Ign*_*ams 5

不可以,因为这需要修改float.__str__(),但不允许您对 C 类型进行猴子修补。请改用字符串插值或格式化。


Nic*_*k T 5

>>> a = 0.1
>>> a
0.10000000000000001
>>> print a
0.1
>>> print "%0.3f" % a
0.100
>>>
Run Code Online (Sandbox Code Playgroud)

Python docsrepr(a)将给出 17 位数字(仅a在交互式提示下键入即可看到,但str(a)(打印时自动执行)四舍五入为 12。

编辑:最基本的黑客解决方案......不过 你必须使用你自己的类,所以......是的。

>>> class myfloat(float):
...     def __str__(self):
...             return "%0.3f" % self.real
>>> b = myfloat(0.1)
>>> print repr(b)
0.10000000000000001
>>> print b
0.100
>>>
Run Code Online (Sandbox Code Playgroud)


Wid*_*jet 5

我今天遇到了这个问题,我想出了一个不同的解决方案。如果您担心打印时的外观,您可以将标准输出文件对象替换为自定义文件对象,该对象在调用 write() 时会搜索任何看起来像浮点数的内容,并将它们替换为您自己的格式他们。

class ProcessedFile(object):

    def __init__(self, parent, func):
        """Wraps 'parent', which should be a file-like object,
        so that calls to our write transforms the passed-in
        string with func, and then writes it with the parent."""
        self.parent = parent
        self.func = func

    def write(self, str):
        """Applies self.func to the passed in string and calls
        the parent to write the result."""
        return self.parent.write(self.func(str))

    def writelines(self, text):
        """Just calls the write() method multiple times."""
        for s in sequence_of_strings:
            self.write(s)

    def __getattr__(self, key):
        """Default to the parent for any other methods."""
        return getattr(self.parent, key)

if __name__ == "__main__":
    import re
    import sys

    #Define a function that recognises float-like strings, converts them
    #to floats, and then replaces them with 1.2e formatted strings.
    pattern = re.compile(r"\b\d+\.\d*\b")
    def reformat_float(input):
        return re.subn(pattern, lambda match: ("{:1.2e}".format(float(match.group()))), input)[0]

    #Use this function with the above class to transform sys.stdout.
    #You could write a context manager for this.
    sys.stdout = ProcessedFile(sys.stdout, reformat_float)
    print -1.23456
    # -1.23e+00
    print [1.23456] * 6
    # [1.23e+00, 1.23e+00, 1.23e+00, 1.23e+00, 1.23e+00, 1.23e+00]
    print "The speed of light is  299792458.0 m/s."
    # The speed of light is  3.00e+08 m/s.
    sys.stdout = sys.stdout.parent
    print "Back to our normal formatting: 1.23456"
    # Back to our normal formatting: 1.23456
Run Code Online (Sandbox Code Playgroud)

如果您只是将数字放入字符串中是不好的,但最终您可能希望将该字符串写入某处的某种文件中,并且您可以使用上述对象包装该文件。显然有一点性能开销。

公平警告:我没有在 Python 3 中测试过这个,我不知道它是否有效。