Pythonでのフロートの簡単なきれいな印刷?


93

フロートのリストがあります。単純に言えprintば、次のように表示されます。

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

リストを走査するprint "%.2f"ためにforループが必要になるを使用することもできますが、より複雑なデータ構造では機能しません。次のようなものが欲しい(私はこれを完全に補っている)

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

回答:


23

それは古い質問ですが、潜在的に役立つものを追加します。

Pythonの生のリストで例を書いたことは知っていますが、numpy代わりに配列を使用することにした場合(数値の配列を扱っているように見えるため、例では完全に合法です)、このコマンドは(ほぼ正確に)あります。あなたは作りました:

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

または、本当に正確な数値のすべての小数を表示したいが、たとえば末尾のゼロを取り除きたい場合は、フォーマット文字列を使用して、さらに優れています%g

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

一度だけ印刷し、グローバルな動作を変更しない場合np.array2stringは、上記と同じ引数を使用します。


101

誰もそれを追加していないので、Python 2.6+以降、文字列フォーマットを行うための推奨される方法はformat、Python 3+の準備のためにを使用することです。

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

新しい 文字列フォーマット構文は使用するのは難しくありませんが、それでも非常に強力です。

何かあるかもしれpprintませんが、何も見つかりませんでした。


1
これは私が使用した.replace("'", "")ものでしたが、これらのコンマを取り除くために追加しました。 str(["{0:0.2f}".format(i) for i in a]).replace("'", "")
Steinarr HrafnHöskuldsson2017年

これは文字列のリストを生成します。印刷出力では、すべての要素が''その周りにあります。たとえば、の場合a=[0.2222, 0.3333]、が生成され['0.22', '0.33']ます。
jdhao

頂点とコンマを削除するには、次を使用する必要があります' '.join([{0:0.2f}".format(i) for i in a])
Neb

78

より永続的な解決策は、サブクラス化すること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

サブクラス化の問題floatは、変数の型を明示的に探しているコードを破壊することです。しかし、私が知る限りでは、それが唯一の問題です。そして、単純なx = map(float, x)はへの変換を元に戻しprettyfloatます。

悲劇的なことに、'は不変なfloat.__repr__ので、モンキーパッチだけではできませんfloat

サブクラス化したくないfloatが、関数の定義を気にしない場合map(f, x)は、[f(n) for n in x]


もっと簡単な解決策があると思ったでしょうが、あなたが私の質問に実際に答えるのはあなただけなので、あなたの答えは明らかに最良です。
static_rtti

4
彼はあなたの編集された質問に実際に答える唯一の人です。回答者を中傷することはありませんが、質問を明確にして、私たちが扱っていた情報に基づいて残りの回答者を軽視することはできません。
ジェドスミス

1
私の最初の質問では、forループは良い解決策ではないと考えていたと述べていました(私にとってリストの理解は同じですが、はっきりしていなかったことに同意します)。次回はもっとわかりやすくしてみます。
static_rtti 2009年

2
[xのnに対するf(n)]はmap(f、x)よりもはるかにPython的です。
Robert T. McGibbon 2013年

2
私は必ずしもfloatのサブクラス化を支持するわけではありませんが、型チェックが有効な引数だとは思いません。タイプをチェックする場合はisinstance、ではなく、を使用する必要がありtype()ます。これが正しく行われると、floatのサブクラスは引き続きfloatとしてカウントされます。
zondo 2017年

37

できるよ:

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

3
これは['9.00'、 '0.05'、 '0.03'、 '0.01'、 '0.06'、 '0.08']を出力します-通常は不要な引用符が付いています(フロートの有効なリストが必要です)印刷)
Emile

23

"%.2f"のような文字列を乗算することもできます(例: "%.2f" * 10)。

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

3
とてもエレガント!気に入った
ネイサンフェルマン

2
-1ひどいハック。文字列のフォーマットされた断片を結合し、他の方法では結合しないでください
u0b34a0f6ae

1
そうkaizer.se、あなたは "" .join(["%。2f"%x for x for yourlist])を提案していますか?私はこの種の構築をpythonで行わなければなりません。
Gregg Lind

はい、" ".join("%.2f" % x for x in yourlist)フォーマット文字列と補間値を分離することは、醜いPythonイディオムを使用するよりもはるかに悪いため、私は提案します。
u0b34a0f6ae 2009年

好奇心です。リストが失敗しているときにタプルが機能するのはなぜですか?「タプル」がないとエラーになります。どうして?
Joonho Park

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

これにより、固定精度制約(を使用したフォーマットなど"%.2f")を導入することなく、印刷時のバイナリ表現の丸め誤差を回避できます。

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

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

出力:

9.00, 0.05, 0.03, 0.01, 0.06, 0.08

なぜこれが高くないのか分からない。サードパーティのライブラリに依存しないソリューション!
Fl.pf.

7

最も簡単なオプションは、丸めルーチンを使用することです。

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

これは出力を生成します:

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]

これは素晴らしい答えです
jjz

4

Python 3.1では、コードを変更することなく、デフォルトでそれらをより適切に印刷できると思います。しかし、Python 3.1で動作するように更新されていない拡張機能を使用する場合、これは役に立ちません。


1
Python 3.1は、そのfloat値にマップされる最も短い10進数表現を出力します。例:>>> a、b = float(1.1)、float(1.1000000000000001)>>> a 1.1000000000000001 >>> b 1.1000000000000001 >>> print(a、b)1.1 1.1
Matt Boehm

4

リストカンプはあなたの友達です。

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

それを試してみてください:

>>> 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
ジェネレーター式はさらに良いでしょう: "、" .join( "%。2f"%f for f in list_o_numbers)
efotinis

@efotinisそれらをまだ私のレパートリーに追加していませんが、あなたは正しいです-それはかなりセクシーです。
ジェドスミス

1
@Jed:FAQのセクション「他の人が私のコンテンツを編集できますか?!」:stackoverflow.com/faqをお読みください。すべての編集が良いものであるとは限りませんが、これは本物の改善でした。おそらく、両方のテクニックを回答にリストし、違いについてのメモを追加できますか?
Stephan202、2009年

4

有効桁数を制御するには、フォーマット指定子%gを使用します。

エミールのソリューションにprettylist2fという名前を付けましょう。これが修正されたものです:

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

使用法:

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

有効桁数に柔軟性を持たせたい場合は、代わりにf文字列フォーマットを使用します。

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]

3

あなたはパンダを使うことができます。

これはリストの例です:

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

dict dがあり、そのキーを行にしたい場合:

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

そして、DataFrameにdictを与える別の方法:

P.DataFrame.from_dict(d, orient='index')

2

まず、コレクション内の要素はそれらの表現を印刷します。__repr__およびについて学習する必要があり__str__ます。

これは、print repr(1.1)とprint 1.1の違いです。表現の代わりにそれらすべての文字列を結合しましょう:

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)

注:この例のPython 2.7では、「repr」行と「str」行の結果は同じです。
ToolmakerSteve

2

floatのタプルのリストを出力するためにpprintを使用しようとしているときに、この問題に遭遇しました。ネストされた内包表記は悪い考えかもしれませんが、これが私がしたことです:

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

最初はジェネレータ式を使用しましたが、pprintはジェネレータを再表現しました...


2

Python 3.6以降では、f-stringsを使用できます。

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

コードを非常に読みやすく保ちながら、印刷パラメータを使用できます。

print(*[f"{element:.2f}" for element in list_], sep='|', end='<--')
#9.00|0.05|0.03|0.01|0.06|0.08<--

1

私はこの問題を抱えていましたが、ここでの解決策のどれも私が望んでいたことを正確に実行しませんでした(印刷された出力を有効なpython式にしたいので)。

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

使用法:

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

(私は.format()がより標準的なソリューションであることを知っていますが、これはより読みやすいと思います)


0

私はSilentGhostのコメントに同意します。forループはそれほど悪くありません。あなたはあなたが望むものを達成することができます:

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

3
forループは見苦しくありませんが、この使用法はそれほどPythonicではありません。
ジェドスミス

-1

以下のコードは私にはうまくいきます。

list = map (lambda x: float('%0.2f' % x), list)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.