Fácil impresión bonita de flotadores en python?


Tengo una lista de flotadores. Si simplemente lo print, se muestra así:

[9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]

Podría usar print "%.2f", lo que requeriría un bucle for para recorrer la lista, pero entonces no funcionaría para estructuras de datos más complejas. Me gustaría algo como (estoy completamente haciendo esto)

>>> import print_options
>>> print_options.set_float_precision(2)
>>> print [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
[9.0, 0.05, 0.03, 0.01, 0.06, 0.08]
Author: mskfisher, 2009-10-14

18 answers

Es una vieja pregunta pero añadiría algo potencialmente útil:

Sé que escribiste tu ejemplo en listas de Python sin procesar, pero si decides usar numpy arrays en su lugar (lo que sería perfectamente legítimo en tu ejemplo, porque parece que estás tratando con arrays de números), hay (casi exactamente) este comando que dijiste que inventaste:

import numpy as np
np.set_printoptions(precision=2)

O incluso mejor en su caso si todavía desea ver todos los decimales de números realmente precisos, pero deshacerse de los ceros finales, por ejemplo, utilice la cadena de formato %g:

np.set_printoptions(formatter={"float_kind": lambda x: "%g" % x})

Para imprimir una sola vez y no cambiar el comportamiento global, use np.array2string con los mismos argumentos que los anteriores.

 7
Author: PlasmaBinturong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-03 11:37:16

Como nadie lo ha añadido, debe tenerse en cuenta que a partir de Python 2.6 + la forma recomendada de hacer formatear cadenas es con format, para prepararse para Python 3+.

print ["{0:0.2f}".format(i) for i in a]

El nuevo string formating syntax no es difícil de usar, y sin embargo es bastante potente.

Pensé que podría ser pprint podría tener algo, pero no he encontrado nada.

 76
Author: Esteban Küber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-14 15:41:43

Una solución más permanente es subclase float:

>>> class prettyfloat(float):
    def __repr__(self):
        return "%0.2f" % self

>>> x
[1.290192, 3.0002, 22.119199999999999, 3.4110999999999998]
>>> x = map(prettyfloat, x)
>>> x
[1.29, 3.00, 22.12, 3.41]
>>> y = x[2]
>>> y
22.12

El problema con la subclase float es que rompe el código que está buscando explícitamente el tipo de una variable. Pero por lo que puedo decir, ese es el único problema con él. Y un simple x = map(float, x) deshace la conversión a prettyfloat.

Trágicamente, no puedes simplemente patch-mono float.__repr__, porque float es inmutable.

Si no quieres subclase float, pero no te importa definir una función, map(f, x) es mucho más conciso than [f(n) for n in x]

 68
Author: Robert Rossney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-14 16:57:29

Puedes hacer:

a = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
print ["%0.2f" % i for i in a]
 37
Author: Pablo Santa Cruz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-14 15:12:55

Tenga en cuenta que también puede multiplicar una cadena como "%.2f" (ejemplo: "%.2f " *10).

>>> print "%.2f "*len(yourlist) % tuple(yourlist)
2.00 33.00 4.42 0.31 
 20
Author: dalloliogm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-14 15:10:43
print "[%s]"%", ".join(map(str,yourlist))

Esto evitará los errores de redondeo en la representación binaria cuando se imprima, sin introducir una restricción de precisión fija (como formatear con "%.2f"):

[9.0, 0.053, 0.0325754, 0.0108928, 0.0557025, 0.0793303]
 8
Author: fortran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-14 15:20:26

Creo que Python 3.1 los imprimirá mejor por defecto, sin ningún cambio de código. Pero eso es inútil si usas cualquier extensión que no se haya actualizado para trabajar con Python 3.1

 4
Author: Echo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-14 15:15:42

List comps son tus amigos.

print ", ".join("%.2f" % f for f in list_o_numbers)

Pruébalo:

>>> nums = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999]
>>> print ", ".join("%.2f" % f for f in nums)
9.00, 0.05, 0.03, 0.01
 4
Author: Jed Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-09 23:35:20

La opción más fácil debería ser usar una rutina de redondeo:

import numpy as np
x=[9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]

print('standard:')
print(x)
print("\nhuman readable:")
print(np.around(x,decimals=2))

Esto produce la salida:

standard:
[9.0, 0.053, 0.0325754, 0.0108928, 0.0557025, 0.0793303]

human readable:
[ 9.    0.05  0.03  0.01  0.06  0.08]
 4
Author: Markus Dutschke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-14 13:29:33

Podrías usar pandas.

Aquí hay un ejemplo con una lista:

In: import pandas as P
In: P.set_option('display.precision',3)
In: L = [3.4534534, 2.1232131, 6.231212, 6.3423423, 9.342342423]
In: P.Series(data=L)
Out: 
0    3.45
1    2.12
2    6.23
3    6.34
4    9.34
dtype: float64

Si tienes un dict d, y quieres sus claves como filas:

In: d
Out: {1: 0.453523, 2: 2.35423234234, 3: 3.423432432, 4: 4.132312312}

In: P.DataFrame(index=d.keys(), data=d.values())
Out:  
    0
1   0.45
2   2.35
3   3.42
4   4.13

Y otra forma de dar dict a un DataFrame:

P.DataFrame.from_dict(d, orient='index')
 3
Author: ifmihai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-12 07:10:16
l = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]

Python 2:

print ', '.join('{:0.2f}'.format(i) for i in l)

Python 3:

print(', '.join('{:0.2f}'.format(i) for i in l))

Salida:

9.00, 0.05, 0.03, 0.01, 0.06, 0.08
 3
Author: Chikipowpow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-24 16:05:00

Primero, los elementos dentro de una colección imprimen su repr. deberías aprender sobre __repr__ y __str__.

Esta es la diferencia entre print repr(1.1) y print 1.1. Unamos todas esas cadenas en lugar de las representaciones:

numbers = [9.0, 0.053, 0.0325754, 0.0108928, 0.0557025, 0.07933]
print "repr:", " ".join(repr(n) for n in numbers)
print "str:", " ".join(str(n) for n in numbers)
 2
Author: u0b34a0f6ae,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-14 16:13:40

Me encontré con este problema al intentar usar pprint para generar una lista de tuplas de flotadores. Las comprensiones anidadas pueden ser una mala idea, pero esto es lo que hice:

tups = [
        (12.0, 9.75, 23.54),
        (12.5, 2.6, 13.85),
        (14.77, 3.56, 23.23),
        (12.0, 5.5, 23.5)
       ]
pprint([['{0:0.02f}'.format(num) for num in tup] for tup in tups])

Usé expresiones generadoras al principio, pero pprint solo repred el generador...

 2
Author: kitsu.eb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-28 00:02:05

Tuve este problema, pero ninguna de las soluciones aquí hizo exactamente lo que quería (quiero que la salida impresa sea una expresión válida de python), así que qué tal esto:

prettylist = lambda l : '[%s]' % ', '.join("%.2f" % f for f in l)

Uso:

>>> ugly = [9.0, 0.052999999999999999, 0.032575399999999997,
            0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
>>> prettylist = lambda l : '[%s]' % ', '.join("%.2f" % f for f in l)
>>> print prettylist(ugly)
[9.00, 0.05, 0.03, 0.01, 0.06, 0.08]

(Lo sé .format() se supone que es la solución más estándar, pero encuentro esto más legible)

 1
Author: Emile,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-30 10:29:59

El siguiente código funciona bien para mí.

list = map (lambda x: float('%0.2f' % x), list)
 0
Author: Romerito,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-19 17:08:36

Para controlar el número de dígitos significativos, utilice el especificador de formato %g.

Vamos a nombrar la solución de Emile prettylist2f. Aquí está la modificada:

prettylist2g = lambda l : '[%s]' % ', '.join("%.2g" % x for x in l)

Uso:

>>> c_e_alpha_eps0 = [299792458., 2.718281828, 0.00729735, 8.8541878e-12]
>>> print(prettylist2f(c_e_alpha_eps0)) # [299792458.00, 2.72, 0.01, 0.00]
>>> print(prettylist2g(c_e_alpha_eps0)) # [3e+08, 2.7, 0.0073, 8.9e-12]

Si desea flexibilidad en el número de dígitos significativos, use formato de cadena f en su lugar:

prettyflexlist = lambda p, l : '[%s]' % ', '.join(f"{x:.{p}}" for x in l)
print(prettyflexlist(3,c_e_alpha_eps0)) # [3e+08, 2.72, 0.0073, 8.85e-12]
 0
Author: Rainald62,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-05 11:20:29

A partir de Python 3.6, puede usar cadenas f:

list_ = [9.0, 0.052999999999999999, 
         0.032575399999999997, 0.010892799999999999, 
         0.055702500000000002, 0.079330300000000006]

print(*[f"{element:.2f}" for element in list_])
#9.00 0.05 0.03 0.01 0.06 0.08

Puede utilizar los parámetros de impresión manteniendo el código muy legible:

print(*[f"{element:.2f}" for element in list_], sep='|', end='<--')
#9.00|0.05|0.03|0.01|0.06|0.08<--
 0
Author: x0s,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-04 09:12:39

Estoy de acuerdo con el comentario de SilentGhost, el bucle for no es tan malo. Puedes lograr lo que quieres con:

l = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
for x in l: print "%0.2f" % (x)
 -1
Author: PTBNL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-14 15:16:18