Cambiar el formato de impresión flotante predeterminado

Tengo algunas listas y estructuras más complejas que contienen flotadores. Al imprimirlos, veo los flotantes con muchos dígitos decimales, pero al imprimir, no los necesito todos. Así que me gustaría definir un formato personalizado (por ejemplo, 2 o 3 decimales) cuando se imprimen los flotantes.

Necesito usar flotadores y no decimal. Además, no se me permite truncar / redondear flotadores.

¿Hay alguna manera de cambiar el comportamiento predeterminado?

No está permitido hacer monografías de mono, como dijo Ignacio.

Sin embargo, si está terriblemente presionado para hacerlo y sabe algo de C, podría modificar el código fuente del intérprete de Python usted mismo y luego volver a comstackrlo en una solución personalizada. Una vez modifiqué uno de los comportamientos estándar para las listas y fue solo un dolor moderado.

Le sugiero que encuentre una solución mejor, como simplemente imprimir los flotadores con la notación de impresión "%0.2f" :

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

o

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

No, porque eso requeriría la modificación de float.__str__() , pero no se te permite hacer mono de los tipos C Utilice la interpolación de cadenas o el formato en su lugar.

Me encontré con este problema hoy, y se me ocurrió una solución diferente. Si le preocupa cómo se ve cuando se imprime, puede reemplazar el objeto de archivo stdout por uno personalizado que, cuando se llama a write (), busca cualquier cosa que parezca flotante y la reemplaza con su propio formato. ellos.

 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 

No es bueno si solo estás poniendo números en una cadena, pero eventualmente querrás escribir esa cadena en algún tipo de archivo en algún lugar, y quizás puedas envolver ese archivo con el objeto anterior. Obviamente hay un poco de sobrecarga de rendimiento.

Aviso justo: no he probado esto en Python 3, no tengo idea de si funcionaría.

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

De los documentos de Python , repr(a) daría 17 dígitos (como se ve simplemente escribiendo a en el indicador interactivo, pero str(a) (ejecutado automáticamente cuando lo imprime) se redondea a 12.

Edit: La solución de hackeo más básica … Sin embargo, debes usar tu propia clase, así que … sí.

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

Actualizar a Python 3.1. No usa más dígitos de los necesarios.

 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 

Si está utilizando el lenguaje C, puede usar #define o "%*.*f" para hacerlo, por ejemplo

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