はじめに
このセクションは少し逸脱していますが、データを扱う際には、構造化された出力(表など)を生成したい場合がよくあります。たとえば:
Name Shares Price
---------- ---------- -----------
AA 100 32.20
IBM 50 91.10
CAT 150 83.44
MSFT 200 51.23
GE 95 40.37
MSFT 50 65.10
IBM 100 70.44
文字列の書式設定
Python 3.6 以降で文字列を書式設定する方法の 1 つは、f-文字列を使うことです。
>>> name = 'IBM'
>>> shares = 100
>>> price = 91.1
>>> f'{name:>10s} {shares:>10d} {price:>10.2f}'
' IBM 100 91.10'
>>>
{式:書式}の部分が置き換えられます。
これは一般的にprintとともに使用されます。
print(f'{name:>10s} {shares:>10d} {price:>10.2f}')
書式コード
書式コード({}内の:の後)は C 言語のprintf()に似ています。一般的なコードは以下の通りです。
d 10進整数
b 2進整数
x 16進整数
f [-]m.dddddd形式の浮動小数点数
e [-]m.dddddde+-xx形式の浮動小数点数
g 浮動小数点数で、E表記の選択的な使用
s 文字列
c 整数からの文字
一般的な修飾子はフィールド幅と小数精度を調整します。これは一部のリストです。
:>10d 10文字のフィールド内で右寄せの整数
:<10d 10文字のフィールド内で左寄せの整数
:^10d 10文字のフィールド内で中央寄せの整数
:0.2f 2桁の精度を持つ浮動小数点数
辞書の書式設定
値の辞書に文字列の書式設定を適用するには、format_map()メソッドを使用できます。
>>> s = {
'name': 'IBM',
'shares': 100,
'price': 91.1
}
>>> '{name:>10s} {shares:10d} {price:10.2f}'.format_map(s)
' IBM 100 91.10'
>>>
これはf-文字列と同じコードを使用しますが、提供された辞書から値を取得します。
format() メソッド
引数またはキーワード引数に書式設定を適用できるformat()メソッドがあります。
>>> '{name:>10s} {shares:10d} {price:10.2f}'.format(name='IBM', shares=100, price=91.1)
' IBM 100 91.10'
>>> '{:>10s} {:10d} {:10.2f}'.format('IBM', 100, 91.1)
' IBM 100 91.10'
>>>
正直なところ、format()は少し冗長です。私は f-文字列の方が好きです。
C スタイルの書式設定
書式設定演算子%も使用できます。
>>> 'The value is %d' % 3
'The value is 3'
>>> '%5d %-5d %10d' % (3,4,5)
' 3 4 5'
>>> '%0.2f' % (3.1415926,)
'3.14'
これには右辺に単一の項目またはタプルが必要です。書式コードもまた C 言語のprintf()に基づいています。
注:これはバイト文字列で利用可能な唯一の書式設定です。
>>> b'%s has %d messages' % (b'Dave', 37)
b'Dave has 37 messages'
>>> b'%b has %d messages' % (b'Dave', 37) ## %bは%sの代わりに使用できます
b'Dave has 37 messages'
>>>
演習 2.8:数値の書式設定方法
数値を表示する際の一般的な問題は、小数桁数を指定することです。これを解決する方法の 1 つは、f-文字列の使用です。これらの例を試してみてください。
>>> value = 42863.1
>>> print(value)
42863.1
>>> print(f'{value:0.4f}')
42863.1000
>>> print(f'{value:>16.2f}')
42863.10
>>> print(f'{value:<16.2f}')
42863.10
>>> print(f'{value:*>16,.2f}')
*******42,863.10
>>>
f-文字列で使用される書式設定コードの完全なドキュメントは、ここで見つけることができます。書式設定は、時々文字列の%演算子を使用しても行われます。
>>> print('%0.4f' % value)
42863.1000
>>> print('%16.2f' % value)
42863.10
>>>
%と共に使用されるさまざまなコードのドキュメントは、ここで見つけることができます。
printと共に一般的に使用されますが、文字列の書式設定は印刷に縛られるものではありません。フォーマット済みの文字列を保存したい場合は、変数に割り当てるだけです。
>>> f = '%0.4f' % value
>>> f
'42863.1000'
>>>
演習 2.9:データの収集
演習 2.7 では、株式ポートフォリオの損益を計算するreport.pyというプログラムを書きました。この演習では、これを次のような表を生成するように修正し始めます。
| 名前 | 株数 | 価格 | 変動 |
|---|---|---|---|
| AA | 100 | 9.22 | -22.98 |
| IBM | 50 | 106.28 | 15.18 |
| CAT | 150 | 35.46 | -47.98 |
| MSFT | 200 | 20.89 | -30.34 |
| GE | 95 | 13.48 | -26.89 |
| MSFT | 50 | 20.89 | -44.21 |
| IBM | 100 | 106.28 | 35.84 |
このレポートでは、「価格」は株式の現在の株価であり、「変動」は初期購入価格からの株価の変動です。
上記のレポートを生成するには、まず表に表示されるすべてのデータを収集する必要があります。株式のリストと価格の辞書を入力として受け取り、上記の表の行を含むタプルのリストを返すmake_report()関数を書きます。
この関数をreport.pyファイルに追加します。対話的に試した場合の動作方法は次のとおりです。
>>> portfolio = read_portfolio('/home/labex/project/portfolio.csv')
>>> prices = read_prices('/home/labex/project/prices.csv')
>>> report = make_report(portfolio, prices)
>>> for r in report:
print(r)
('AA', 100, 9.22, -22.980000000000004)
('IBM', 50, 106.28, 15.180000000000007)
('CAT', 150, 35.46, -47.98)
('MSFT', 200, 20.89, -30.339999999999996)
('GE', 95, 13.48, -26.889999999999997)
...
>>>
演習 2.10:フォーマット済みの表の出力
演習 2.9 の for ループをやり直しますが、print 文を変更してタプルをフォーマットします。
>>> for r in report:
print('%10s %10d %10.2f %10.2f' % r)
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
...
>>>
また、値を展開して f-文字列を使用することもできます。たとえば:
>>> for name, shares, price, change in report:
print(f'{name:>10s} {shares:>10d} {price:>10.2f} {change:>10.2f}')
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
...
>>>
上記の文を取り出して、report.pyプログラムに追加します。プログラムにmake_report()関数の出力を取り込ませ、表示されるように整ったフォーマットの表を出力させます。
演習 2.11:ヘッダーの追加
次のようなヘッダー名のタプルがあったとします。
headers = ('Name', 'Shares', 'Price', 'Change')
上記のヘッダー名のタプルを受け取り、各ヘッダー名が 10 文字幅のフィールドで右寄せになり、各フィールドが 1 つの空白で区切られた文字列を作成するコードをプログラムに追加します。
' Name Shares Price Change'
ヘッダーを受け取り、ヘッダーとその後に続くデータの間の区切り文字列を作成するコードを書きます。この文字列は、各フィールド名の下にたくさんの「-」文字だけです。たとえば:
'---------- ---------- ---------- -----------'
完了したら、プログラムはこの演習の冒頭に示されている表を生成する必要があります。
| 名前 | 株数 | 価格 | 変動 |
|---|---|---|---|
| AA | 100 | 9.22 | -22.98 |
| IBM | 50 | 106.28 | 15.18 |
| CAT | 150 | 35.46 | -47.98 |
| MSFT | 200 | 20.89 | -30.34 |
| GE | 95 | 13.48 | -26.89 |
| MSFT | 50 | 20.89 | -44.21 |
| IBM | 100 | 106.28 | 35.84 |
演習 2.12:フォーマットのチャレンジ
価格に通貨記号($)を含め、出力が次のようになるようにコードをどのように修正すればよいでしょうか。
| 名前 | 株数 | 価格 | 変動 |
|---|---|---|---|
| AA | 100 | $9.22 | -22.98 |
| IBM | 50 | $106.28 | 15.18 |
| CAT | 150 | $35.46 | -47.98 |
| MSFT | 200 | $20.89 | -30.34 |
| GE | 95 | $13.48 | -26.89 |
| MSFT | 50 | $20.89 | -44.21 |
| IBM | 100 | $106.28 | 35.84 |
まとめ
おめでとうございます!あなたはフォーマットの実験を完了しました。あなたのスキルを向上させるために、LabEx でさらに実験を行って練習してください。