2009-10-14 3 views
62

J'ai une liste de flottants. Si je simplement print, il apparaît comme ceci:Une jolie impression facile de flotteurs en python?

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

je pourrais utiliser print "%.2f", ce qui nécessiterait une boucle for pour parcourir la liste, mais cela ne fonctionnerait pas pour les structures de données plus complexes. Je voudrais quelque chose comme (je suis complètement invente)

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

Répondre

64

Une solution plus permanente est-à-sous-classe 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 

Le problème avec subclassing float est qu'il casse le code qui cherche explicitement le type d'une variable . Mais pour autant que je sache, c'est le seul problème avec ça.Et un simple x = map(float, x) annule la conversion à prettyfloat. Tragiquement, vous ne pouvez pas corriger le singe float.__repr__, car float est immuable.

Si vous ne voulez pas sous-classe float, mais ne me dérange pas la définition d'une fonction, map(f, x) est beaucoup plus concis que [f(n) for n in x]

+0

J'aurais pensé qu'il y avait une solution plus simple, mais votre réponse est clairement la meilleure, puisque vous êtes le seul à réellement répondre à ma question. –

+4

Il est le seul à réellement répondre à votre question -edited-. Ne pas déprécier le répondeur, mais vous ne pouvez pas clarifier une question et ensuite affiner le reste des répondeurs en fonction de l'information que nous travaillions avec. –

+0

Ma question initiale mentionnait que je considérais qu'une boucle for n'était pas une bonne solution (pour moi, la compréhension d'une liste est la même, mais je suis d'accord que ce n'était pas clair). Je vais essayer d'être plus clair la prochaine fois. –

17

Notez que vous pouvez aussi multiplier une chaîne comme « % .2f » (exemple: « % .2f » * 10).

>>> print "%.2f "*len(yourlist) % tuple(yourlist) 
2.00 33.00 4.42 0.31 
+2

très élégant! Je l'aime –

+2

-1 hack terrible. Joignez-vous à des morceaux de chaînes formatés, pas autrement, s'il vous plaît – u0b34a0f6ae

+1

donc kaizer.se, proposez-vous "" .join (["%. 2f"% x pour x dans votre liste]). Je dois faire ce genre de construction en python. –

4

Liste comps sont votre ami.

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

Essayez:

>>> 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 
+5

Une expression génératrice serait encore mieux: "," .join ("%. 2f"% f pour f dans list_o_numbers) – efotinis

+0

@efotinis N'ont pas encore ajouté ça à mon répertoire , mais tu as raison - c'est très sexy. –

+0

S'il vous plaît ne pas modifier ma réponse. –

37

Vous pouvez faire:

a = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006] 
print ["%0.2f" % i for i in a] 
+3

Cela va imprimer ['9,00', '0,05', '0,03', '0,01', '0,06', '0,08'] - avec des guillemets, ce que vous ne voulez généralement pas (je préfère avoir une liste valide de floats imprimés) – Emile

4

Je crois que Python 3.1 leur imprimer plus agréable par défaut, sans changement de code. Mais cela ne sert à rien si vous utilisez toutes les extensions qui n'ont pas été mis à jour pour fonctionner avec Python 3.1

+1

Python 3.1 imprime la représentation décimale la plus courte qui correspond à cette valeur flottante. Par exemple: >>> a, b = flotteur (1.1), flotteur (1,1000000000000001) >>> un 1,1000000000000001 >>> b 1,1000000000000001 >>> print (a, b) 1.1 1.1 –

-1

Je suis d'accord avec le commentaire de SilentGhost, la boucle est pas si mal. Vous pouvez obtenir ce que vous voulez:

l = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006] 
for x in l: print "%0.2f" % (x) 
+3

Alors que pour les boucles ne sont pas moche, cette utilisation n'est pas terriblement pythonique. –

8
print "[%s]"%", ".join(map(str,yourlist)) 

Cela évitera les erreurs d'arrondi dans la représentation binaire lors de l'impression, sans introduire une contrainte de précision fixe (comme formating avec "%.2f"):

[9.0, 0.053, 0.0325754, 0.0108928, 0.0557025, 0.0793303] 
62

Comme personne ne l'a ajouté, il est à noter qu'à partir de Python 2.6+, la méthode recommandée pour faire string formating est avec format, pour se préparer à Python 3+.

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

The newstring formating syntax n'est pas difficile à utiliser, mais est tout à fait powerfull.

Je pensais que peut-être pprint pourrait avoir quelque chose, mais je n'ai rien trouvé.

+1

C'est celui que j'ai utilisé mais j'ai ajouté '.replace (" '"," ")' pour me débarrasser de ces virgules. 'Str ([" {0: 0.2f} ". Format (i) pour i dans a]). Replace (" '"," ")' –

+0

Cela produira une liste de chaînes de caractères. Dans la sortie imprimée, chaque élément a '' ''' autour de lui. Par exemple, pour 'a = [0.2222, 0.3333]', il produira '['0.22', '0.33']'. – jdhao

2

D'abord, les éléments d'une collection impriment leur repr. vous devriez en apprendre davantage sur __repr__ et __str__.

C'est la différence entre l'impression repr (1.1) et l'impression 1.1. Joignons toutes ces chaînes au lieu des représentations:

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

NOTE: Dans Python 2.7, pour cet exemple, les résultats de la ligne "repr" et de la ligne "str" ​​sont identiques. – ToolmakerSteve

2

Je viens de rencontrer ce problème tout en essayant d'utiliser pprint pour produire une liste de tuples de flotteurs. compréhensions emboîtées peut-être une mauvaise idée, mais voici ce que je faisais:

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]) 

J'utilise des expressions du générateur au début, mais pprint juste repred le générateur ...

3

Vous pouvez utiliser pandas géants.

est un exemple Voici une liste:

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 vous avez un dict d, et que vous voulez ses clés sous forme de lignes:

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 

Et une autre façon de donner dict à un dataframe :

1

J'ai eu ce problème, mais aucune des solutions ici fait exactement ce que je voulais (je veux la sortie imprimée est une expression de python valide), alors que diriez-vous:

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

Utilisation:

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

(je sais .format() est censé être la solution plus standard, mais je trouve cela plus lisible)

0

Le code ci-dessous fonctionne bien pour moi.

list = map (lambda x: float('%0.2f' % x), list) 
2
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)) 

Sortie:

9.00, 0.05, 0.03, 0.01, 0.06, 0.08 
4

L'option la plus facile à utiliser devrait être une routine d'arrondi:

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

Cela produit la sortie:

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

Pour contrôler le nombre de chiffres significatifs , utilisez le spécificateur de format% g.

Appelons la solution d'Emile prettylist2f.Voici modifié un:

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

Utilisation:

>>> 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 vous voulez la flexibilité du nombre de chiffres significatifs, utilisez f-string formatting à la place:

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] 
Questions connexes