print number float python formatting floating-point pretty-print

number - print python float format



Formateo de flotantes en Python sin ceros superfluos (14)

¿Qué tal si probamos el enfoque más fácil y probablemente el más efectivo? El método normalize () elimina todos los ceros finales a la derecha.

from decimal import Decimal print (Decimal(''0.001000'').normalize()) # Result: 0.001

Funciona en Python 2 y Python 3 .

-- Actualizado --

El único problema que señaló @ BobStein-VisiBone es que números como 10, 100, 1000 ... se mostrarán en representación exponencial. Esto se puede solucionar fácilmente usando la siguiente función:

from decimal import Decimal def format_float(f): d = Decimal(str(f)); return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()

¿Cómo formatear un flotante para que no contenga los ceros que siguen? En otras palabras, quiero que la cadena resultante sea lo más corta posible ...

Me gusta:

3 -> "3" 3. -> "3" 3.0 -> "3" 3.1 -> "3.1" 3.14 -> "3.14" 3.140 -> "3.14"


A OP le gustaría eliminar ceros superfluos y hacer que la cadena resultante sea lo más corta posible.

Encuentro que el formato exponencial% g acorta la cadena resultante para valores muy grandes y muy pequeños. El problema viene para los valores que no necesitan notación exponencial, como 128.0, que no es ni muy grande ni muy pequeña.

Esta es una forma de formatear números como cadenas cortas que usan la notación exponencial% g solo cuando Decimal.normalize crea cadenas que son demasiado largas. Esta podría no ser la solución más rápida (ya que usa Decimal.normalize)

def floatToString (inputValue, precision = 3): rc = str(Decimal(inputValue).normalize()) if ''E'' in rc or len(rc) > 5: rc = ''{0:.{1}g}''.format(inputValue, precision) return rc inputs = [128.0, 32768.0, 65536, 65536 * 2, 31.5, 1.000, 10.0] outputs = [floatToString(i) for i in inputs] print(outputs) # [''128'', ''32768'', ''65536'', ''1.31e+05'', ''31.5'', ''1'', ''10'']


Aquí hay una solución que funcionó para mí. Es una combinación de la solution de PolyMesh y el uso de la nueva syntax .format() .

for num in 3, 3., 3.0, 3.1, 3.14, 3.140: print(''{0:.2f}''.format(num).rstrip(''0'').rstrip(''.''))

Salida :

3 3 3 3.1 3.14 3.14


Después de revisar las respuestas a varias preguntas similares, esta parece ser la mejor solución para mí:

def floatToString(inputValue): return (''%.15f'' % inputValue).rstrip(''0'').rstrip(''.'')

Mi razonamiento

%g no elimina la notación científica.

>>> ''%g'' % 0.000035 ''3.5e-05''

15 decimales parece evitar un comportamiento extraño y tiene mucha precisión para mis necesidades.

>>> (''%.15f'' % 1.35).rstrip(''0'').rstrip(''.'') ''1.35'' >>> (''%.16f'' % 1.35).rstrip(''0'').rstrip(''.'') ''1.3500000000000001''

Pude haber usado el format(inputValue, ''.15f''). en lugar de ''%.15f'' % inputValue , pero eso es un poco más lento (~ 30%).

Podría haber usado Decimal(inputValue).normalize() , pero esto también tiene algunos problemas. Por un lado, es MUCHO más lento (~ 11x). También encontré que, aunque tiene una precisión bastante grande, aún sufre pérdidas de precisión cuando usa normalize() .

>>> Decimal(''0.21000000000000000000000000006'').normalize() Decimal(''0.2100000000000000000000000001'') >>> Decimal(''0.21000000000000000000000000006'') Decimal(''0.21000000000000000000000000006'')

Lo que es más importante, todavía estaría convirtiendo a Decimal de un float que puede hacer que termines con algo más que el número que colocaste ahí. Creo que Decimal funciona mejor cuando la aritmética se mantiene en Decimal y el Decimal se inicializa con una cadena.

>>> Decimal(1.35) Decimal(''1.350000000000000088817841970012523233890533447265625'') >>> Decimal(''1.35'') Decimal(''1.35'')

Estoy seguro de que el problema de precisión de Decimal.normalize() se puede ajustar a lo que se necesita utilizando la configuración de contexto, pero considerando la velocidad lenta y sin necesidad de una precisión ridícula y el hecho de que todavía estaría convirtiendo de una carroza y perdiendo precisión de todos modos, no pensé que valiera la pena seguir.

No me preocupa el posible resultado "-0" ya que -0.0 es un número de coma flotante válido y, de todos modos, probablemente sea una ocurrencia rara, pero como mencionó que desea mantener el resultado de la cadena lo más corto posible, siempre podría usar un condicional adicional a muy poco costo adicional de velocidad.

def floatToString(inputValue): result = (''%.15f'' % inputValue).rstrip(''0'').rstrip(''.'') return ''0'' if result == ''-0'' else result


Para flotar, podrías usar esto:

def format_float(num): return (''%i'' if num == int(num) else ''%s'') % num

Pruébalo:

>>> format_float(1.00000) ''1'' >>> format_float(1.1234567890000000000) ''1.123456789''

Para Decimal ver solución aquí: https://.com/a/42668598/5917543


Puede usar %g para lograr esto:

''%g''%(3.140)

o, para Python 2.6 o mejor:

''{0:g}''.format(3.140)

De los documentos para format : g causa (entre otras cosas)

los ceros finales insignificantes [a ser] eliminados del significado, y el punto decimal también se elimina si no hay dígitos restantes que lo siguen.


Puede usar max () de esta manera:

print(max(int(x), x))


Puedes lograr eso de la manera más pitonica así:

python3:

"{:0.0f}".format(num)


Si bien el formateo es probablemente la forma más Pythonic, aquí hay una solución alternativa que utiliza la herramienta more_itertools.rstrip .

import more_itertools as mit def fmt(num, pred=None): iterable = str(num) predicate = pred if pred is not None else lambda x: x in {".", "0"} return "".join(mit.rstrip(iterable, predicate)) assert fmt(3) == "3" assert fmt(3.) == "3" assert fmt(3.0) == "3" assert fmt(3.1) == "3.1" assert fmt(3.14) == "3.14" assert fmt(3.140) == "3.14" assert fmt(3.14000) == "3.14" assert fmt("3,0", pred=lambda x: x in set(",0")) == "3"

El número se convierte en una cadena, que está desprovista de caracteres finales que satisfacen un predicado. La definición de función fmt no es necesaria, pero se usa aquí para probar las afirmaciones, que todas pasan. Nota: funciona en las entradas de cadena y acepta predicados opcionales.

Consulte también los detalles de esta biblioteca de terceros, more_itertools .


Si puede vivir con 3. y 3.0 apareciendo como "3.0", un enfoque muy simple que elimina franjas a la derecha de representaciones flotantes:

print("%s"%3.140)

(gracias @ellimilial por señalar las excepciones)


Simplemente puede usar format () para lograr esto:

format(3.140, ''.10g'') donde 10 es la precisión que desea.


Use% g con un ancho lo suficientemente grande, por ejemplo ''% .99g''. Se imprimirá en notación de punto fijo para cualquier número razonablemente grande.

EDITAR: no funciona

>>> ''%.99g'' % 0.0000001 ''9.99999999999999954748111825886258685613938723690807819366455078125e-08''


Yo, yo haría (''%f'' % x).rstrip(''0'').rstrip(''.'') - garantiza el formato de punto fijo en lugar de la notación científica, etc., etc. Sí, no tan resbaladizo y elegante como %g , pero funciona (y no sé cómo forzar que %g nunca use notación científica ;-).


>>> str(a if a % 1 else int(a))