なぜ{:.3f}ではできないのか
'{:フォーマット文字列}'.format(x)
の実際の動作はビルトイン関数format(x, フォーマット文字列)
やそこから呼び出されるx.__format__(フォーマット文字列)
が返すものと決まっているようですが、Pythonの基本的なデータ型(intとかfloat)あるいはビルトインライブラリーに含まれるデータ型についてはPython言語の開発をしているチームが仕様を決めていると思います。
一方numpyはPythonのビルトインライブラリーではなくサードパーティーライブラリとでもいうべきものなので、なぜ{:.3f}でフォーマットできないかといえばnumpyの設計者が「できない仕様」と決めたからといえましょう。
numpy設計者は例えば次のような感じにndarrayをフォーマットする仕組みにもできたと思います。
python
1# 非常に大雑把な例
2class Array:
3 def __init__(self, a):
4 self.a = a
5
6 def __str__(self):
7 return str(self.a)
8
9 def __format__(self, format_spec):
10 return '[' + ', '.join(map(lambda x: format(x, format_spec), self.a)) + ']'
11
12
13a = Array([1.1, 2.2, 3.3, 3+1j])
14print(a) # => [1.1, 2.2, 3.3, (3+1j)]
15print('{:.3f}'.format(a)) # => [1.100, 2.200, 3.300, 3.000+1.000j]
なぜそうしなかったか自分はテキトーに想像することしかできませんが、例えば
・配列のフォーマットには単に値の精度をどうするかだけでなく、行方向や列方向の最大行数・最大文字数を制限したいだとか様々な要求がある
・numpy.ndarrayは基本的に同じ列の要素の印字幅(文字数)を自動的に合わせようとする。.3f
のような全体桁数を曖昧にできるstr.formatの仕様とは充分マッチしないかも知れない。
・それらの要求を満たし、しかも標準のフォーマット文字列の仕様からおおきく逸脱しないようにうまくformat文字列の仕様をnumpyで決めるのはなかなか大変だった
・そういうわけでnumpy独自のAPIを用意した
・APIでフォーマットの詳細を決めることにしたため、仕様の統一性のためstr.formatに精度のみ指定できるという(よく言えば便利、悪く言えば中途半端な)仕様は導入しなかった
・・・なんて思いました。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/02/16 17:19