2010-07-16 124 views
12

我有一些列表和更復雜的結構包含浮動。當打印它們時,我看到有很多十進制數字的浮點數,但是在打印時,我不需要所有浮點數。 所以我想定義一個自定義格式(例如2或3小數),當浮動打印。更改默認浮動打印格式

我需要使用浮動而不是十進制。此外,我不允許截斷/舍入浮游物。

有沒有辦法改變默認行爲?

回答

7

你不允許以monkeypatch C類型,如伊格納西奧說。然而,如果你非常急於這樣做,並且你知道一些C,你可以自己修改Python解釋器源代碼,然後重新編譯爲一個自定義解決方案。一旦我修改了列表的標準行爲之一,這只是一個溫和的痛苦。

我建議你找一個更好的解決方案,如剛剛打印花車與"%0.2f" printf的符號:

for item in mylist: 
    print '%0.2f' % item, 

print " ".join('%0.2f' % item for item in mylist) 
+0

問題是我已經漂浮在列表中,當我打印(列表)時,我無法控制它。 (這也適用於其他對象,順便說一句)。 修改源代碼是可行的,因爲我知道C,但並不完全是我所想的。謝謝。 – AkiRoss 2010-07-16 13:29:55

+0

@AkiRoss:那麼你想要修復的是清單,而不是浮動... – 2010-07-16 13:33:15

+0

@AkiRoss,如果你想更多的控制只是單獨打印項目。 – 2010-07-16 13:34:45

3

不,因爲那需要修改float.__str__(),但是您不允許monkeypatch C類型。改用字符串插值或格式。

+0

其實,它需要修改'float .__ repr__'。'str'只使用12位有效數字。 – dan04 2010-07-19 08:17:26

1
>>> a = 0.1 
>>> a 
0.10000000000000001 
>>> print a 
0.1 
>>> print "%0.3f" % a 
0.100 
>>> 

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 
>>> 
0

升級到Python 3.1。它不會使用比必要更多的數字。

Python 3.1.2 (r312:79147, Apr 15 2010, 15:35:48) 
[GCC 4.4.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> 0.1 
0.1 
+0

已經在使用它。這不是重點,但謝謝你的提示。 – AkiRoss 2010-07-19 09:17:57

-1

如果您使用的是C語言,您可以使用#define"%*.*f"要做到這一點,例如

printf("%*.*f",4,2,variable); 
+1

他明確使用python標籤,因此他沒有使用C – Bruce 2011-06-09 15:51:13

2

我今天遇到了這個問題,我想出了一個不同的解決方案。如果您擔心打印時看起來像什麼,則可以使用自定義的對象來替換stdout文件對象,當調用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 

這是沒有好,如果你只是把數字轉換成字符串,但最終你可能會想要寫一個字符串到某種文件的地方,你可能能包住該文件與上面的對象。很顯然,性能開銷有點兒。

公平的警告:我還沒有在Python 3中測試過,我不知道它是否可行。