翻譯:《實用的Python編程》02_03_Formatting
目錄 | 上一節 (2.2 容器) | 下一節 (2.4 序列)
2.3 格式化
雖然本節稍微有點離題,但是當處理數據時,通常想要生成結構化的輸出(如表格)。示例:
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+ 中,格式化字符串的一種方法是使用 f-strings:
>>> name = 'IBM'
>>> shares = 100
>>> price = 91.1
>>> f'{name:>10s} {shares:>10d} {price:>10.2f}'
' IBM 100 91.10'
>>>
{expression:format} 部分會被取代。
f-strings 通常和 print() 函數一起使用:
print(f'{name:>10s} {shares:>10d} {price:>10.2f}')
格式碼
格式碼(在 {} 內 : 之后)與 C 語言的 printf() 函數類似。常見格式碼包括:
d Decimal integer
b Binary integer
x Hexadecimal integer
f Float as [-]m.dddddd
e Float as [-]m.dddddde+-xx
g Float, but selective use of E notation
s String
c Character (from integer)
常見的修飾符可調整字段寬度和數的精度。這是部分內容:
:>10d Integer right aligned in 10-character field
:<10d Integer left aligned in 10-character field
:^10d Integer centered in 10-character field
:0.2f Float with 2 digit precision
字典格式化
可以使用字符串的 format_map() 方法將字符串格式化應用于值的字典:
>>> s = {
'name': 'IBM',
'shares': 100,
'price': 91.1
}
>>> '{name:>10s} {shares:10d} {price:10.2f}'.format_map(s)
' IBM 100 91.10'
>>>
雖然 format_map() 和 f-strings 使用相同的格式碼,但是是從提供的字典中獲取值。
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-strings。
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 %n messages' % (b'Dave', 37)
b'Dave has 37 messages'
>>>
練習
練習 2.8:如何格式化數字
打印數字常見的一個問題就是指定數字的小數位數。其中的一種解決方法就是使用 f-strings。請嘗試以下示例:
>>> 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-strings 使用的格式碼的完整文檔在 這里 可以找到。有時,也使用字符串操作符 % 執行格式化。
>>> 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。在本練習中,需要修改這個程序來生成如下表格:
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
在此表格中,"Price" 是當前股價,"Change" 是當前股價與原始購買股價的差。
為了生成上述表格,首先需要收集表中展示的所有數據。編寫 make_report() 函數,以股票列表和價格字典作為輸入,并返回一個包含上表中所有行的元組列表。
把 make_report() 函數添加到 report.py 文件中。如果交互式地執行該函數,則應該按以下步驟進行:
>>> portfolio = read_portfolio('Data/portfolio.csv')
>>> prices = read_prices('Data/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 循環,但是請更改打印語句以格式化元祖。
>>> 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-strings 擴展值。例如:
>>> 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,每個字段使用單個空格分隔。
' Name Shares Price Change'
編寫在標題和數據之間創建分隔字符串的代碼。分隔字符串指每個字段名下的一串下劃線("-")字符。例如:
'---------- ---------- ---------- -----------'
當完成后,程序應生成本節頂部所示的表。
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:格式化挑戰
如何修改代碼使得價格包括貨幣符號($),并且像下面這樣輸出:
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
浙公網安備 33010602011771號