python格式化字符輸出 str.format()

需求分析

字符串格式化是編程常見操作,python中也對此有強(qiáng)大的支持。python3.6中有利用%str.format()來操作的,python3.6也新增了f-string的方法。本文簡單講解str.format(),通過其繪制一個(gè)簡單表格。如下圖

看起來還算不錯(cuò)吧

下面是一些原數(shù)據(jù),三個(gè)列表。

label = ['TP', 'FN', 'FP','TN', 'Sn/RE(%)', 'Sp(%)', 'Acc', 'Mcc', 'PPV/PR(%)', 'Str(%)', 'FPR(%)']
data1 = ['209', '43', '25', '227', '82.9365%', '90.0794%', '86.5079%', '73.2029%', '89.3162%', '86.5079%', '9.9206%']
data2 = ['227', '25', '43', '209', '90.0794%', '82.9365%', '86.5079%', '73.2029%', '84.0741%', '86.5079%', '17.0635%']

利用 ' '.join()

不知道格式化字符串的話,可能會(huì)通過下面代碼實(shí)現(xiàn)來輸出數(shù)據(jù):

for i in [label, data1, data2]:
    print('    '.join(i)) # join()

上面的代碼可能會(huì)造成下面的現(xiàn)象,沒有對齊。

沒對齊的表格

有的會(huì)想是因?yàn)閘abel數(shù)據(jù)和data的數(shù)據(jù)長度不一樣,調(diào)一下相隔的寬度就行。' '.join() 這個(gè)是固定的,調(diào)節(jié)' '的大小,列表所有元素相鄰間隔就變動(dòng)了,要找到一個(gè)合適的間隔不太容易。

% 方法

接觸過格式化字符串的話,可能先想到的是 %。上面代碼改為

for i in [label, data1, data2]:
    s = '%s  %s  %s %s  %s  %s  %s   %s  %s  %s   %s'%(i[0],i[1],i[2]...i[10])#偷懶,明白就好
    print(s)

然后結(jié)果是這樣:


還是不對齊

你看了看,這不是join()函數(shù),這是利用 % 可以自由更改它們之間的間距,然后你修改了代碼:

for v,i in enumerate([label, num1, num2]):
    if v == 10:
        s = '%s  %s   %s  %s    %s      %s     %s     %s    %s    %s   %s'%(i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7],i[8],i[9],i[10])
    else:
        s = '%s  %s  %s  %s  %s  %s  %s   %s  %s  %s   %s'%(i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7],i[8],i[9],i[10])
    print(s)

結(jié)果很不錯(cuò),他們已經(jīng)對齊了:


成功了

但是,過程確實(shí)不容易,且不說%后面的跟著的一長串字符,不能利用拆包,只能一個(gè)蘿卜一個(gè)坑的對應(yīng)這放進(jìn)去,容易出現(xiàn)小失誤。接下來介紹str.format()就比這優(yōu)雅。不過我覺得新手應(yīng)該比較喜歡用%吧,,因?yàn)檫@比str.format()少打一個(gè)單詞。。。

str.format()

直接上代碼了

直接這樣和利用%是一樣的
str_f = '{}  {}  {}  {}    {}    {}   {}    {}    {}    {}    {}'
#加索引,和上面不加就本例子來說,效果差不多。不過加了能加清楚有多少個(gè),和有其它用途)
#str_f = '{0}  {1}  {2}  {3}    {4}    {5}   {6}    {7}    {8}    {9}    {10}'
for i in [label, data1, data2]:
    print(str_f.format(*i))

#繼續(xù)改進(jìn)
str_f1 = '{:^8}  {:^8}  {:^8}  {:^8}    {:^8}    {:^8}   {:^8}    {:^8}  |  {:^9}    {:^8}  |  {:^8}'
for i in [label, data1, data2]:
    print(str_f1.format(*i))

#這個(gè)你會(huì)發(fā)現(xiàn),前四個(gè)數(shù)字用不了那么大的間距,繼續(xù)修改代碼。
print('-'*116)
str_f2 = '{:^4} | {:^4} | {:^4} | {:^4}  |  {:^8}  |  {:^8} |  {:^8}  |  {:^8}  |  {:^9}  |  {:^8}  |  {:^8}'
for i in [label, data1, data2]:
    print(str_f2.format(*i))
print('-'*116)
效果

下面是{}里面的一些格式說明符。

#摘自python官方文檔
format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]
fill        ::=  <any character>
align       ::=  "<" | ">" | "=" | "^"
sign        ::=  "+" | "-" | " "
width       ::= integer
precision   ::= integer
type        ::=  "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"

主要講解下文本所用到的格式說明符,'{}'就像excel里的單元格,不過這里的{}與{}之間可以設(shè)置不同字符如,'{} {}';align就像是單元格居中(…^),居左(<)還是居中(>)。width是單元格的寬度,在實(shí)際中就是根據(jù)字符的長度可以設(shè)置不同的寬度。本文中就分別設(shè)置了4,8。fill 是填充物,將單元格剩余空格填充指定字符,sign是指定數(shù)字前的符號(+,-),precision是數(shù)字精度長度。type,數(shù)據(jù)類型。(%也有上述差不多的功能,不過之前未曾提及。感興趣,請上網(wǎng)搜索)
還有個(gè)值得提的是str.format()里的參數(shù)支持拆包,從上面代碼可以看出不用像%那樣將每個(gè)元素都寫出來了。


f-string

f-string是python3.6新增的,此處簡要只寫相關(guān)代碼。

#打印出來效果和上面str_f1差不多。
for i in [label, data1, data2]:
    a = ' | '.join([f"{a:{9}}" for a in (i)])
    fs = f'{a}'
    print(fs)

加幾個(gè)官方例子:

>>> value = 4 * 20
>>> f'The value is {value}.'
'The value is 80.'

>>> f'{{ {4*10} }}'
'{ 40 }'
>>> f'{{{4*10}}}'
'{40}'

>>> def foo():
...   return 20
...
>>> f'result={foo()}'
'result=20'


了解更多str.format()請點(diǎn)擊官網(wǎng)
了解更多f-string請點(diǎn)擊pep498
python控制臺動(dòng)畫

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容