Python: リスト要素の桁揃えなどのフォーマット方法

 数値計算をしていると、想定通りの値が得られているか確認するためにprint関数で表示することがあるが、計算結果は大抵float型であり、リスト要素である。

 そういった計算結果を、小数第3桁で四捨五入などフォーマットされた文字列として出力する方法を考える。 例えば、[3.3333, 4.4444, 5.5555] といったリストを[3.33, 4.44, 5.56]のように出力する。


 正確な計算結果ではなく、丸められた値でコンパクトに表示をしたい時、format関数によりprint('{:.2f}'.format(num))のようにフォーマットしたい。NumPyライブラリを導入している場合は簡単に実現できるが、導入していない場合、工夫が必要になる。

NumPyを使う場合

> import numpy as np
> nums = np.array([3.3333, 4.4444, 5.5555])
> print(np.round(nums, 2))
[ 3.33 4.44 5.56]

非常にシンプルに実現できる。

また一時的でなく、常に特定の桁数で値を表示させたければ、numpy.set_printoptionsで表示桁precisionを与えることで実現できる。

> import numpy as np
> np.set_printoptions(precision=2)
> nums = np.array([3.3333, 4.4444, 5.5555])
> print(nums)
[ 3.33 4.44 5.56]

デフォルトの設定precision=8に設定し直さない限り常に小数第2桁までの表示となる。

NumPyを使わない場合

 フォーマット形式を直接リストには適用できないため、工夫が必要となる。例えば、

nums = [3.3333, 4.4444, 5.5555]

のようなリストがあった時、これを小数第2桁までの値で出力させたい場合、次の3つの考え方ができる。

フォーマット済み文字列のリストを生成

   > print(['{:.2f}'.format(n) for n in nums])
   ['3.33', '4.44', '5.56']

リストの要素を全て小数第2桁までの値にフォーマットし、新たなリストとしている。この場合、:.2fを適宜指定することで、表示桁数を揃えたり、文字列要素のリストについても応用できる。

リスト要素をmap関数でそれぞれ丸めてから出力

> print(list(map(round, nums, [2]*len(nums))))
[3.33, 4.44, 5.56]

リストの要素それぞれにround(n, 2)を適用している。[2]*len(nums)の2を別の値にすることで桁数を調整したり、round関数を別の関数に書き換えることで応用できる。

リストの要素を展開してフォーマット

> print(('{:.2f}, '*len(nums)).format(*nums))
3.33, 4.44, 5.56, 

リストを展開することで、各要素に対してフォーマットが適用できるが、文字列中の{:.2f}とリスト要素の数を合わせなければ、前から順番に参照していく。すべての要素を出力させたければ上記のように*len(nums)で文字列を繰り返して同数になるように記述をする。

 リストとして扱う必要がないため、改行や値の名前を加えるなど柔軟に出力できる一方で、大量の計算結果を機械的に出力する場合、カッコやカンマを手作業で加える必要があるため、面倒である。


 特に理由がなければNumPyを導入すると良い。NumPyを使わない場合、指数表記など文字列としてのフォーマットを望まない限り、map関数を使う方法がもっともきれいな出力が得られるが、print関数内が複雑になる上、出力する上で一時的に桁数を調整していることが明記されないため、コードの視認性は悪くなるように思う。