Изменить формат печати по умолчанию - PullRequest
14 голосов
/ 16 июля 2010

У меня есть несколько списков и более сложные структуры, содержащие поплавки. При их печати я вижу числа с большим количеством десятичных цифр, но при печати они мне не нужны. Поэтому я хотел бы определить пользовательский формат (например, 2 или 3 десятичных знака) при печати чисел с плавающей запятой.

Мне нужно использовать числа с плавающей запятой, а не десятичные. Кроме того, я не могу усекать / округлять поплавки.

Есть ли способ изменить поведение по умолчанию?

Ответы [ 6 ]

9 голосов
/ 16 июля 2010

Вам не разрешено монкипечать C-типы, как сказал Игнасио.

Однако, если вы ужасно переживаете это и знаете какой-то C, вы можете сами изменить исходный код интерпретатора Python, а затем скомпилировать его в собственное решение. Однажды я изменил одно из стандартных поведений для списков, и это была только умеренная боль.

Я предлагаю вам найти лучшее решение, например, просто распечатать числа с плавающей запятой с пометкой "%0.2f" printf:

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

или

print " ".join('%0.2f' % item for item in mylist)
4 голосов
/ 16 июля 2010

Нет, потому что для этого потребуется изменить float.__str__(), но вы не можете монтировать патчи C-типов.Вместо этого используйте интерполяцию или форматирование строки.

3 голосов
/ 21 мая 2015

Я столкнулся с этой проблемой сегодня и нашел другое решение.Если вы беспокоитесь о том, как это выглядит при печати, вы можете заменить объект файла 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, я понятия не имею, сработает ли это.

1 голос
/ 16 июля 2010
>>> a = 0.1
>>> a
0.10000000000000001
>>> print a
0.1
>>> print "%0.3f" % a
0.100
>>>

Из документов Python , repr(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 голосов
/ 09 июня 2011

Если вы используете язык C, вы можете использовать #define или "%*.*f" для этого, например

printf("%*.*f",4,2,variable);
0 голосов
/ 19 июля 2010

Обновление до 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
...