萬字長文,史上最全Python字符串格式化講解
后臺回復(fù)【大禮包】送你Python自學(xué)大禮包
后臺回復(fù)【大禮包】送你Python自學(xué)大禮包
今天分享的是一篇來自群友小王(王暖暖)同學(xué)的投稿,可以說是非常的細(xì)節(jié),堪稱史上最全對字符串格式化輸出的講解了!
上個周周末看到”pandas數(shù)據(jù)格式化處理“的時候想著把(設(shè)置小數(shù)位數(shù),設(shè)置百分位,設(shè)置千位分隔符)這些個知識點知識點總結(jié)一下,記一下筆記。可是,記著記著發(fā)現(xiàn)怎么越來越多,而且都和字符串格式化離不開關(guān)系,于是我又轉(zhuǎn)頭去復(fù)習(xí)了一下字符串格式化部分的知識。
但是我萬萬沒想到啊,本以為不多的知識點,但是仔細(xì)整理下來 ,想要把絕大部分都搞清楚,還是花了我一周多的時間,特別是g和G的使用,百度,google說的太籠統(tǒng)了,后來去官網(wǎng)看,但是我官網(wǎng)的真是太官方了,我還真不太能理解其中的一些個意思,于是就開始磨,一點一點試錯,索性還是鼓搗清楚十之八九,于是就形成了下面你所看到的這篇帖子......
目錄:
一、% 格式化
二、str.format()格式化
三、f-string格式化
四、format()
五、總結(jié)
參考


一、% 格式化
1.語法
"%[(name)][flags][width][.precison]type"?%?待格式化數(shù)據(jù)
2.參數(shù)
(1)?%:?占位符;
(2)?(name):命名占位字符;
(3)?flags可選:
????1)?+:?右對齊,正數(shù)加正號,負(fù)數(shù)加負(fù)號;
????2)?-:?左對齊,正數(shù)無符號,負(fù)數(shù)加負(fù)號;
????3)?空格:?右對齊(默認(rèn)的對齊方式),正數(shù)前加空格,負(fù)數(shù)前加負(fù)號;
????4)?0:?右對齊,以0填充,正數(shù)無符號,負(fù)數(shù)加負(fù)號,并將符號放置在0最左側(cè);
(4)?width:?占位寬度,?若指定寬度小于原數(shù)據(jù)長度則按原長度數(shù)據(jù)輸出;
(5) .precison:?小數(shù)點后保留位數(shù);在字符串中則表示截取/字符串切片;
(6)?type:?詳見如下...
3.type
(1)?s:?string,?字符串;
(2)?d:?decimal?integer,?十進(jìn)制數(shù);
(3)?i:?integer,?用法同%d;
(4)?u:?unsigned?integer,?無符號十進(jìn)制數(shù);
(5)?f:?float,?浮點數(shù)(默認(rèn)保留小數(shù)點后6位);
(6)?F:?Float,?浮點數(shù)(默認(rèn)保留小數(shù)點后6位);
(7)?e:?exponent,?將數(shù)字表示為科學(xué)計數(shù)法(小寫e,?默認(rèn)保留小數(shù)點后6位);
(8)?E:?Exponent,?將數(shù)字表示為科學(xué)計數(shù)法(大寫E,?默認(rèn)保留小數(shù)點后6位);
(9)?o:?octal,?八進(jìn)制數(shù)(即0-7);
(10)?x:?hexdecimal,?十六進(jìn)制數(shù)(即0-9a-f);
(11)?X:?Hexdecimal,?十六進(jìn)進(jìn)制數(shù)(0-9A-F);
(12)?g:?general?format,?通用格式,詳見如下...;
(13)?G:?General?format,?通用格式,詳見如下...;
(14)?%c:?character,?將十進(jìn)制數(shù)轉(zhuǎn)換為所對應(yīng)的unicode值;
(15)?%r:?representation,?調(diào)用__repr__魔法方法輸出;
(16)?%%:?轉(zhuǎn)義%,輸出百分號。
4.補充
四舍五入 vs 四舍六入五雙
四舍五入
在需要將一個"小數(shù)保留小數(shù)點后n位"或"保留n位有效數(shù)字"的時候即需要對數(shù)字進(jìn)行適當(dāng)?shù)娜∩幔缧枰獙?.125四舍五入保留到小數(shù)點后兩位的結(jié)果應(yīng)該為1.13。但是,如果你無論使用%還是使用format的格式化形式,得到的結(jié)果和預(yù)期的卻大相近庭,如下:
print("{:.2f}".format(1.125))?
>>>?1.12
print("%.2f"?%?1.125)?????????
>>>?1.12
從上面的結(jié)果可以看到,將1.125保留兩位小數(shù)的結(jié)果為1.12, 并非1.13,這是為什么呢?請繼續(xù)往下看(四舍六入五雙)...
四舍六入五雙
精確n位數(shù)字或保留n位小數(shù),采用如下的規(guī)則(以保留n位小數(shù)為例):
a. 四舍: 保留n位小數(shù),若第n+1位≤4, 則舍去;
b. 六入: 保留n位小數(shù),若第n+1位≥6, 則第n位進(jìn)1;
c. 五雙: 保留n位小數(shù),若第n+1位=5, 若 如果第n+1位后面沒有任何數(shù)字, 則第n位數(shù)字為偶數(shù)就舍去n+1位,第n位數(shù)字為奇數(shù)則進(jìn)1;
如果第n+1位后還存在不為0的任何數(shù)字,則第n位數(shù)字無論是奇數(shù)還是偶數(shù)都進(jìn)1。
print("{:.2f}".format(1.125))需要保留兩位小數(shù)(n=2),則觀察小數(shù)點后第二位數(shù)字2的后一位(n+1位)。第n+1為5,且5后沒有其它數(shù)字,第n位2為偶數(shù),所以直接舍去,故最后的結(jié)果為1.12。
十進(jìn)制轉(zhuǎn)二進(jìn)制
a. 十進(jìn)制整數(shù)轉(zhuǎn)二進(jìn)制: 除2取余,逆序排列;
b. 十進(jìn)制浮點數(shù)轉(zhuǎn)二進(jìn)制: 乘基取整;
不精確尾數(shù)
十進(jìn)制浮點數(shù)的小數(shù)部分在轉(zhuǎn)換為二進(jìn)制的時候有可能出現(xiàn)無限小數(shù)無法乘盡的情況。但計算機無法處理無限小數(shù),會將十進(jìn)制浮點數(shù)對應(yīng)的二進(jìn)制數(shù)最多保留53位,53位后面的數(shù)據(jù)直接截斷,從而導(dǎo)致在將二進(jìn)制浮點數(shù)轉(zhuǎn)換回十進(jìn)制的時候出現(xiàn)不精確的現(xiàn)象。
Decimal
如上述所言,因為有的浮點數(shù)可能存在不精確尾數(shù)的情況,導(dǎo)致一些需要精密計算的數(shù)據(jù)難以處理,每個不精確的小數(shù)累積起來可能造成嚴(yán)重的數(shù)據(jù)失信,所以可以使用python標(biāo)準(zhǔn)模塊decimal模塊下的Decimal類進(jìn)行處理。
Decimal提供了十進(jìn)制浮點數(shù)的精密運算支持,使用Decimal所表示的浮點數(shù)即為精確小數(shù),不存在不精確尾數(shù)的情況。此外,Decimal還提供了諸多用于"取舍"的模式,如ROUND_UP(遠(yuǎn)離0取舍),ROUDN_DOWN(趨向0取舍), ROUND_HALF_UP(四舍五入,half即表示5的意思,up表示遠(yuǎn)離0的方向)等。
Decimal(value)中value可以傳遞整數(shù), 字符串, 元組, 浮點數(shù)或另一個Decimal對象,推薦使用字符串傳遞參數(shù)給value,如直接傳遞浮點數(shù)給value依舊會存在不精確尾數(shù)。
所以想要實現(xiàn)"四舍五入"的功能即可使用Decimal,如下所示:
from?decimal?import?Decimal,?ROUND_HALF_UP
print(Decimal("1.125").quantize(Decimal(".00"),?rounding=ROUND_HALF_UP))
>>>?1.13
__str__和__repr__
格式化字符參數(shù)中有一個%r, 此處的r即是調(diào)用__repr__魔法方法,其功能和__str___類似,二者區(qū)別如下:
class?Animal:
????def?__init__(self,?name):
????????self.name?=?name
????def?__str__(self):
????????return?"我是"?+?self.name
????def?__repr__(self):
????????return?"我的名字是"?+?self.name
??
??
if?__name__?==?"__main__":
????cat?=?Animal("小黑")
????print(cat)
如果在Animal一類中既沒有定義__str__ 也沒有定義__repr__魔法方法,那么print輸出打印cat對象將得到cat對象的內(nèi)存地址,類似<__main__.Animal object at 0x0000017F2D384970>;
如果只定義了__str__ 或__repr__中的一個,那么print(cat)都將輸出其對應(yīng)的返回值,類似返回"我是小黑"或"我的名字是小黑";
如果既定義了__str__和__repr__兩個魔法方法,那么print(cat)將輸出__str__對應(yīng)的返回值;__repr__和__str__的區(qū)別在于,一個側(cè)重用戶,一個側(cè)重開發(fā)人員。如果定義了__repr__方法,那么在一些編輯器(Jupyter Notebook, JypyterLab)或終端中直接傳遞對象名即可獲取__repr__的返回值,如下圖所示:

5.用法詳解
name
(1.1)?不指定name
1)?單個數(shù)據(jù)
????print("|我是%s"?%?"王暖暖|")?
????>>>?|我是王暖暖|
2)?多個數(shù)據(jù):?使用元組
????print("|我是%s,今年%d歲|"?%?("王暖暖",?18))?
????>>>?|我是王暖暖,今年18歲|
(1.2)?指定name:?使用字典
1)?單個數(shù)據(jù)
????print("|我是%(name)s|"?%?{"name":?"王暖暖"})
????>>>?|我是王暖暖|
2)?多個數(shù)據(jù)
????print("|我叫%(name)s, 今年%(age)d歲。|"?%?{"name":?"王暖暖",?"age":?18})
????>>>?|我叫王暖暖,?今年18歲。|
(1.3)?單個數(shù)據(jù)對應(yīng)多個占位
????#?元組內(nèi)元素數(shù)量必須和占位符數(shù)量統(tǒng)一
????print("|我是?%s?%s?%s!!!|"?%?("王暖暖",?"王暖暖",?"王暖暖"))
????#?使用字典則必須指明鍵值對
????print("|我是?%(name)s?%(name)s?%(name)s!!!|"?%?({"name":?"王暖暖"}))
????>>>?|我是王暖暖?王暖暖?王暖暖!!!|
flags + width
#?依次按flags中"+",?"-",?"?",?"0"結(jié)合width=10演示
(2.1)?字符串:?
????print("|%+10s|"?%?"王暖暖")?
????>>>?|???????王暖暖|?#?字符串右對齊
????
????print("|%-10s|"?%?"王暖暖")?
????>>>?|王暖暖???????|?#?字符串左對齊
????
????print("|%?10s|"?%?"王暖暖")?
????>>>?|???????王暖暖|?#?字符串右對齊
????
????print("|%010s|"?%?"王暖暖")?
????>>>?|???????王暖暖|?#?字符串右對齊
(2.2)?正整數(shù)
????print("|%+10d|"?%?26)?
????>>>?|???????+26|?#?正整數(shù)右對齊,正數(shù)加正號
????
????print("|%-10d|"?%?26)?
????>>>?|26????????|?#?正整數(shù)左對齊,正數(shù)無符號
????
????print("|%?10d|"?%?26)?
????>>>?|????????26|?#?正整數(shù)右對齊,正數(shù)前加空格
????
????print("|%010d|"?%?26)?
????>>>?|0000000026|?#?正整數(shù)右對齊,正數(shù)無符號,以0填充
(2.3)?負(fù)整數(shù)
????print("|%+10d|"?%?-26)?
????>>>?|???????-26|?#?負(fù)整數(shù)右對齊,負(fù)數(shù)加負(fù)號
????
????print("|%-10d|"?%?-26)?
????>>>?|-26???????|?#?負(fù)整數(shù)左對齊,負(fù)數(shù)加負(fù)號
????
????print("|%?10d|"?%?-26)?
????>>>?|???????-26|?#?負(fù)整數(shù)右對齊,負(fù)數(shù)加負(fù)號
????
????print("|%010d|"?%?-26)?
????>>>?|-000000026|?#?負(fù)整數(shù)右對齊,負(fù)數(shù)加負(fù)號,?符號和數(shù)字之前填充0
(2.4)?正浮點數(shù)
????#?如未指定浮點數(shù)精度,默認(rèn)保留6位小數(shù),其余均用空格填充(如指定0則用0填充);若width小于浮點數(shù)的數(shù)位則width無效。
????print("|%+10f|"?%?2.2)?
????>>>?|?+2.200000|?#?正浮點數(shù)加正號右對齊,小數(shù)部分以0填充
????
????print("|%-10f|"?%?2.2)?
????>>>?|2.200000??|?#?正浮點數(shù)左對齊,小數(shù)點后為空格
????
????print("|%?10f|"?%?2.2)?
????>>>?|??2.200000|?#?正浮點數(shù)右對齊,浮點數(shù)前為空格
????
????print("|%010f|"?%?2.2)?
????>>>?|002.200000|?#?正浮點數(shù)右對齊,小數(shù)點前以0填充
(2.5)?負(fù)浮點數(shù)
????print("|%+10f|"?%?-2.2)?
????>>>?|?-2.200000|?#?負(fù)浮點數(shù)加負(fù)號右對齊,小數(shù)部分以0填充
????
????print("|%-10f|"?%?-2.2)?
????>>>?|-2.200000?|?#?負(fù)浮點數(shù)加負(fù)號左對齊,小數(shù)點后為空格
????
????print("|%?10f|"?%?-2.2)?
????>>>?|?-2.200000|?#?負(fù)浮點數(shù)加負(fù)號右對齊,其余用空格填充
????
????print("|%010f|"?%?-2.2)?
????>>>?|-02.200000|?#?負(fù)浮點數(shù)加負(fù)號右對齊,其余用0填充,注意符號在最左側(cè)
(2.6)?詳詳解
1)?print("|%+15f|"?%?22.6)?
???>>>?|?????+22.600000|
????a)?未指定保留位數(shù),故小數(shù)點后占6位,用0填充;
????b)?小數(shù)點占1位,"+"號占1位,共2位;
????c)?小數(shù)點前系數(shù)"22"占2位;
????c)?其余均用空格填充,故空格占5位,總計15位.
2)?print("|%+015f|"?%?22.6)?
???>>>?|+0000022.600000|
????a)?未指定保留位數(shù),故小數(shù)點后占6位,用0填充;
????b)?小數(shù)點占1位,"+"號占1位,共2位;
????c)?小數(shù)點前系數(shù)22占2位;
????d)?其余均用0填充,故小數(shù)點前的"0"占5位,總計15位;
????e)?注意:?此處同時使用了"+"和"0",配合二者的功能使用。
????
3)?print("|%+15.3f|"?%?22.66)??
???>>>?|????????+22.660|
????a)?指定保留小數(shù)位數(shù)為3位,不足的用0填充;
????b)?其余的用空格填充;
4)?print("|%+015.3f|"?%?22.66)?
???>>>?|+0000000022.660|
????a)?指定保留小數(shù)位數(shù)為3位,不足的用0填充;
????b)?其余的用"0"填充;
precision
(3.1)?字符串
????如果待格式化數(shù)據(jù)為字符串則表示字符串截取
????print("|%.2s|"?%?"python")?
????>>>?|py|
(3.2)?浮點數(shù)
????保留小數(shù)點后.precision數(shù)字
????print("|%(num).2f|"?%?{"num":?0.145})?
????>>>?|0.14|
????
????print("|%(num).2f|"?%?{"num":?1.145})?
????>>>?|1.15|
????
????print("|%(num).2f|"?%?{"num":?2.145})?
????>>>?|2.15|
????
????print("|%(num).2f|"?%?{"num":?3.145})?
????>>>?|3.15|
????注意:?此處列舉的數(shù)字均存在"不精確尾數(shù)"和"四舍六入五雙"兩種情況
(3.3)?科學(xué)計數(shù)
????print("|%.3f用科學(xué)計數(shù)法表示寫作%.2E|"?%?(40.125,?40.125))
????>>>?|40.125用科學(xué)計數(shù)法表示寫作4.01E+01|
????解析:?先將40.125轉(zhuǎn)為科學(xué)計數(shù)法形式:?4.0125*10^1(4.0125乘以10的1次方);
?????????而后再對4.0125精確到小數(shù)點后位,?即4.01;
?????????最后用e或E分隔系數(shù)和指數(shù),即為4.01E+01
????????????
(3.4)?g/G模式:?詳見如下...
type
(1)?s:?字符串?
????print("|我是%s|"?%?"王暖暖")?>>>?|我是王暖暖|
????
(2)?d,?i,?u:?十進(jìn)制數(shù)字
????print("|我最喜歡的十進(jìn)制數(shù)是%d|"?%?26)
????print("|我最喜歡的十進(jìn)制數(shù)是%i|"?%?26)
????print("|我最喜歡的十進(jìn)制數(shù)是%u|"?%?26)
????>>>?|我最喜歡的十進(jìn)制數(shù)是26|
(3)?f:?浮點數(shù)(默認(rèn)保留6位小數(shù))
????#?保留小數(shù)詳情見上...
????print("|這是一個浮點數(shù)%f|"?%?2.26)
????>>>?|這是一個浮點數(shù)2.260000|
(4)?e,?E:?科學(xué)計數(shù)
?print("|%f用科學(xué)計數(shù)法表示寫作%e|"?%?(4.145,?4.145))
????>>>?|4.145000用科學(xué)計數(shù)法表示寫作4.145000e+00|
????
????print("|%.3f用科學(xué)計數(shù)法表示寫作%.2E|"?%?(4.145,?4.145))
????>>>?|4.145用科學(xué)計數(shù)法表示寫作4.14E+00|
????
(2)?o:?八進(jìn)制
????print("|十進(jìn)制%(num)d對應(yīng)的八進(jìn)制數(shù)為%(num)o|"?%?{"num":?26})?
????>>>?|十進(jìn)制26對應(yīng)的八進(jìn)制數(shù)為32|
????
(3)?x,?X:?十六進(jìn)制
????print("|十進(jìn)制%(num)d對應(yīng)的十六進(jìn)制數(shù)為%(num)x|"?%?{"num":?26})
????>>>?|十進(jìn)制26對應(yīng)的十六進(jìn)制數(shù)為1a|
????
????print("|十進(jìn)制%(num)d對應(yīng)的十六進(jìn)制數(shù)為%(num)X|"?%?{"num":?26})
????>>>?|十進(jìn)制26對應(yīng)的十六進(jìn)制數(shù)為1A|
(6)?g,?G詳見如下...
(7)?c:?unicode字符
????print("|%d對應(yīng)的unicode字符為:%c|"?%?(226,?226))
????>>>?|226對應(yīng)的unicode字符為:a|
????????
(12)?%r:?representation,?調(diào)用傳入對象的__repr__方法的返回值
????經(jīng)測試,無論是使用%s類型還是%r類型,使用JypyterLab均直接輸出格式化結(jié)果,其二者的卻別在于,使用%r模式會在字符串?dāng)?shù)據(jù)的左右兩側(cè)加上'',?詳見下圖...
????
(11)?%%:?轉(zhuǎn)義%。
如果有待格式化數(shù)據(jù)需要輸出百分號(%),需要使用%%進(jìn)行轉(zhuǎn)義
print("|I'm?%d%%?sure.|"?%?100)?>>>?|I'm?100%?sure.|



二、str.format()格式化
1.語法
"{[index][:[[fill]align][sign][#][0][width][grouping_option][.precision][type]]}".format()
2.參數(shù)詳解
(1)?index:?待格式化字符的索引或鍵,若占位符數(shù)量和參數(shù)數(shù)量不一致時必須指定索引;
(2)?fill:?填充字符,可為任意字符;
????
(3)?align:?對齊方式(常配合width使用),可選:
?#?和Excel中輸入文本和數(shù)字的默認(rèn)對齊方式一致
????1)?<:?左對齊(字符串默認(rèn)對齊方式);
????2)?>:?右對齊(數(shù)字默認(rèn)對齊方式);
????3)?^:?居中對齊;
????4)?=:?內(nèi)容右對齊,將符號(+或-)放置在填充字符的左側(cè),僅對數(shù)字類型有效;
????
(4) sign:?有無符號,可選:
????1)?+:?正數(shù)加正號,負(fù)數(shù)加負(fù)號;
????2)?-:?正數(shù)不變,負(fù)數(shù)加負(fù)號(默認(rèn));
????3)?空格:?正數(shù)加空格,負(fù)數(shù)加負(fù)號;
????????
(5)?#:?
???????a.?對于整數(shù),在輸出值分別添加響應(yīng)的0b,?0o,?0x前綴;
???????b.?對于浮點數(shù)和復(fù)數(shù),?在輸出值保留小數(shù)點符號;
???????c.?在g/G模式下,保留末尾的0;
????????
(6)?0:?若未設(shè)置對齊方式,在width前加一個0將為數(shù)字類型啟用感知正負(fù)號的零填充,等同于設(shè)置fill為0,?align為"=";
(7)?width:?字段總寬度(十進(jìn)制整數(shù)),?所有前綴,分隔符和其它格式化字符之和;?
????
(8)?grouping_option:?設(shè)置分組(分隔):
???????1)?",":?使用逗號作為千位分隔符;
???????2)?"_":?使用_作為分隔符:
??????????a.?對于十進(jìn)制數(shù),?使用_作為千位分隔符;
??????????b.?對于b,?o,?x/X,使用_每4位數(shù)插入一個下劃線;
????????????
(9)?.precision(十進(jìn)制數(shù)):?
???????a.?整數(shù)型不允許設(shè)置precison,?如果設(shè)置即被轉(zhuǎn)換為浮點數(shù);
???????b.?浮點型表示小數(shù)點"后"顯示多少位小數(shù)位數(shù);
???????c.?以g或G格式化表示在小數(shù)點"前后"共顯示多少個數(shù)位;
?????? d. 字符型表示截取多少個字符;
????
(10)?{{或}}:?轉(zhuǎn)義{或},當(dāng)需要輸出{或}的使用使用;
????
(11)?type:?詳見如下...
3.type:
format()格式化與%格式化的type大同小異,以下盡挑重點講解
(1)?b:?binary,?二進(jìn)制;
(3)?g:?general?formatting,?詳見如下...
(4)?G:?General?formatting,?詳見如下...
4.genaral formatting
g和G模式是我花時間最多去琢磨的一個點,所以單獨把它抽離出來講解。這里的g字母是general的縮寫,百度可以查到一些資料,說某種條件下, g模式等同于f模式或e模式。但是,實際上,g與f, e這兩種模式還有一些區(qū)別,詳見如下:
(1)?給定精度
?對于給定精度?p?>=?1,會將數(shù)值舍入到p個有效數(shù)位,再將結(jié)果以小數(shù)或科學(xué)計數(shù)法進(jìn)行格式化,精度0會被視為等價于精度1。
?1)?對于浮點數(shù):
????????print("|{:.2G}|".format(3.125))
????????先將3.125轉(zhuǎn)換為科學(xué)計數(shù)法表示,即為3.125*10^0;
????????此時,指定的精度p=2,?表示小數(shù)點前后共保留2個有效數(shù)位,?指數(shù)exp=0,則
????????如果-4?≤?exp?-4?≤?0?2),該數(shù)將使用"f"模式和精度p-1-exp(2-1-0=1)格式化,故
????????結(jié)果為:?|3.1|?
????????????
????2)?對于Decimal:
????????print("|{:.2G}|".format(Decimal("4.145")))
????????先將Decimal("4.145")轉(zhuǎn)換為科學(xué)計數(shù)法表示,即為4.145*10^0;
????????此時,指定的精度p=2,?表示小數(shù)點前后共保留2個有效數(shù)位,指數(shù)exp=0,?則
????????如果-6?≤?exp?-6?≤?0?2),?該數(shù)將使用"f"模式和精度p-1-exp(2-1-0)格式化,故
????????結(jié)果為:?|4.1|
????????????
????3)?如果不滿足m?≤?exp?-4或-6),?則使用"e"模式和精度p-1表示:
????????print("|{:.3G}|".format(4225.125))
????????先將4225.125轉(zhuǎn)換為科學(xué)計數(shù)法表示,即為4.225125*10^3;
????????此時,指定的精度p=3,?exp=3,?則
????????-4?≤?exp?-4?≤?3?3)不成立,所以使用"e"模式和精度p-1(3-1=2)表示,故
????????結(jié)果為:?|4.23E+03|
??print("|{:.3G}|".format(Decimal("4225.256")))
????????同理如上,結(jié)果為|4.23E+3|
????????
(2)?未給定精度
?如未指定精度,會對浮點數(shù)采用6個有效數(shù)位的精度;?對于 Decimal,結(jié)果的系數(shù)會沿用原值的系數(shù)數(shù)位。
????只有很小的數(shù)字或很大的數(shù)字才會使用"e"模式表示,?其余的均用"f"模式表示:
????????a.?絕對值小于等于1e-6(0.000001)的數(shù)使用"e"模式表示;
????????b.?小數(shù)點前的數(shù)位大于6的數(shù)使用"e"模式表示。
????例如:
?????print("|{:G}|".format(0.0000002))
????????>>>?|2E-07|
????????print("|{:G}|".format(5555555.6666))
????????>>>?|5.55556E+06|
????????
(3)?注意點
?1)
?需要注意的是,g/G和f,e/E并不完全相同,主要體現(xiàn)在精度的處理上。
????對于f而言,精度p指的是保留小數(shù)點后p位小數(shù);
????對于e而言,精度p指的是將數(shù)據(jù)轉(zhuǎn)換為科學(xué)計數(shù)法后保留小數(shù)點后p位;
????而g/G模式下,則表示小數(shù)點前后保留p位有效數(shù)字。
????print("|{:.3G}|".format(5555.6666))?
????>>>?|5.56E+03|
????
????print("|{:.3E}|".format(5555.6666))?
????>>>?|5.556E+03|
????
????print("|{:.3f}|".format(5555.6666))?
????>>>?|5555.667|
????
????2)?如果小數(shù)點之后沒有數(shù)位,則小數(shù)點也會被略去,除非使用了#選項
????print("{:G}".format(333.0))??
????>>>?333
????
????print("{:#G}".format(333.0))?
????>>>?333.000
????
????print("{:f}".format(333.0))??
????>>>?333.000000
????
?print("{:E}".format(333.0))??
????>>>?3.330000E+02
5.用法詳解
基于前文已經(jīng)詳細(xì)講解了%格式化中各個參數(shù)的用法,此處便不再做過多贅述,更多以實例講解,如有必要再做具體解析。
index
print("|我叫{},?今年{}歲.|".format("Zack",?18))???#?不指定index
print("|我叫{0},?今年{1}歲.|".format("Zack",?18))?#?數(shù)字
print("|我叫{0[0]},?今年{0[1]}歲.|".format(("Zack",?18,?)))?#?元組?
print("|我叫{name},?今年{age}歲.|".format(name="Zack",?age=18))?#?關(guān)鍵字參數(shù)
info?=?{"name":?"Zack",
????????"age":?18}
print("|我叫{name},?今年{age}歲.|".format(**info))?#?字典
>>>?|我叫Zack,?今年18歲。|
print("|該復(fù)數(shù)的實部為{0.real},?虛部為{0.imag}|".format(1+2j))
>>>?|該復(fù)數(shù)的實部為1.0,?虛部為2.0|
fill+width+align
fill?=?&
align?=?None
width?=?10
(1)?不指定align,無法指定fill,?默認(rèn)為空格
????print("|{0:10}|".format("王暖暖"))?
????>>>?|王暖暖???????|???#?字符串
????
????print("|{0:10}|".format(226))????
????>>>?|???????226|?????#?數(shù)字
(2)?指定align,?fill=&,?width=10
?print("|{0:&<10}|".format("王暖暖"))?
????>>>?|王暖暖&&&&&&&|
????
????print("|{0:&>10}|".format("王暖暖"))?
????>>>?|&&&&&&&王暖暖|
????
????print("|{0:&^10}|".format("王暖暖"))?
????>>>?|&&&王暖暖&&&&|
????
?print("|{0:&=10}|".format(-226))????
????>>>?|-&&&&&&226|????#?符號放置最左側(cè)
sign+align+fill+width
#?均以數(shù)字演示
sign=None
align=None
fill=*
width=10
(1)?"+":
????print("|{0:*<+10}|".format(226))??
????>>>?|+226******|
????
????print("|{0:*>+10}|".format(-226))?
????>>>?|******-226|
????
(2)?"-":?
????print("|{0:*<-10}|".format(226))??
????>>>?|226*******|
????
????print("|{0:*>-10}|".format(-226))?
????>>>?|******-226|
(3)?"?":
????print("|{0:*10}|".format(226))??
????>>>?|***?226***|?#?整數(shù)前有空格
????
????print("|{0:*10}|".format(-226))?
????>>>?|***-226***|?#?負(fù)數(shù)前有負(fù)號????
g/G
(1)?b,?o,?x/X
????print("|{0:#b}|".format(226))?
????>>>?|0b11100010|
????
????print("|{0:#o}|".format(226))?
????>>>?|0o342|
????
????print("|{0:#X}|".format(226))?
????>>>?|0XE2|
(2)?浮點數(shù)和復(fù)數(shù)
????即使指定小數(shù)點后保留0位數(shù)字,依舊保留小數(shù)點
????print("|{:.0f}|".format(3.14))??
????>>>?|3|
????
????print("|{:#.0f}|".format(3.14))?
????>>>?|3.|
????
????print("|{:.0f}|".format(1+2J))??
????>>>?|1+2j|
????
????print("|{:#.0f}|".format(1+2J))?
????>>>?|1.+2.j|
(3)?g/G:
????print("{:G}".format(333.0))??
????>>>?333
????print("{:#G}".format(333.0))?
????>>>?333.000
"0"
(1)若未設(shè)置對齊方式,在width前加一個0將為數(shù)字類型啟用感知正負(fù)號的零填充,等同于設(shè)置fill為0,?align為"="
????print("|{0:010}|".format(-3.14))?
????>>>?|-000003.14|
????等同于
????
????print("|{0:0=10}|".format(-3.14))?
????>>>?|-000003.14|
????注意區(qū)別于
????print("|{0:0>10}|".format(-3.14))?
????>>>?|00000-3.14|
????
????此功能等同于%格式化中的"0",?如下所示:
????print("|%010.2f|"?%?-3.14)????????
????>>>?|-000003.14|
group_options
(1)?","千位分隔符
????print("|{0:,}|".format(3141.5926))?
????>>>?|3,141.5926|
(2)?"_"
?1)?對于十進(jìn)制數(shù),使用"_"作為千位分隔符
????print("|{0:_}|".format(3141.5926))?
????>>>?|3_141.5926|
?
????2)?對于b,?o,?x/X,使用"_"每四位插入一個下劃線
????print("|{0:_b}|".format(12345))?
????>>>?|11_0000_0011_1001|
????
????print("|{0:_o}|".format(12345))?
????>>>?|3_0071|????????????
{{或}}轉(zhuǎn)義
print("This?is?a?set:?{{{0}}}".format("1,?2,?3"))?
>>>?This?is?a?set:?{1,?2,?3}
補充
在處理精密數(shù)據(jù)的時候,因為不精確尾數(shù)的關(guān)系,可能導(dǎo)致一些數(shù)據(jù)失信,如下所示,將數(shù)據(jù)保留兩位小數(shù),有的精確為0.14而有的卻精確為0.15。雖然Decimal可以處理此類問題,但是經(jīng)過測試,Decimal并不使用于%格式化。傳入Decimal和直接傳入浮點數(shù)的結(jié)果一致,并無任何區(qū)別。故,如果要處理此類問題還是需要使用str.format()形式并傳遞Decimal類型的數(shù)據(jù)。
print("|%.2f|"?%?0.145)????????????
>>>?|0.14|
print("|%.2f|"?%?Decimal("0.145"))?
>>>?|0.14|
print("|%.2f|"?%?1.145)????????????
>>>?|1.15|
print("|%.2f|"?%?Decimal("1.145"))?
>>>?|1.15|
print("|{:.2f}|".format(Decimal("0.145")))?
>>>?|0.14|
print("|{:.2f}|".format(Decimal("1.145")))?
>>>?|1.14|

三、f-string格式化
1.語法
python3.6以后開始支持f-string字符串。f-string即formatting string, 它是str.format()的一個變種,其語法形式之殊途同歸,很多時候使用f-string可以有效減少代碼量,更為清晰易懂。語法:f"{}{}{}"
2.示例
(1)
????name?=?"Zack"
????age?=?18
????print(f"|我是{name},?今年{age}歲|")?
????>>>?|我是Zack,?今年18歲|
????
(2)
?for?p?in?range(3):
????url?=?f"https://www.baidu.com/s?wd=python&pn={p*10}&oq=python"
(3)?可直接調(diào)用對應(yīng)對象的方法和屬性
?channel?=?"ted"
?print(f"|我喜歡觀看{channel.upper()}學(xué)習(xí)英語|")

四、format()
1.語法
# x為需要格式化的數(shù)據(jù),formatter為格式化表達(dá)式,不需要指定{}。
format(x,?formatter)
2.示例
#序列號
nums?=?[1,?2,?3]
serial_nums?=?[format(x,?"0>8")?for?x?in?nums]
print(serial_nums)
>>>?['00000001',?'00000002',?'00000003']

五、總結(jié)
python字符串格式化語法較多,不便記憶,可以在具體需要使用的時候再查詢即可。%格式化可以滿足大多常用的功能,但是處理一些精密化或復(fù)雜的格式化需求的時候就束手無策了,所以推薦使用str.format()或f-string格式化處理字符串。
f-string是str.format()的一個分之,在一些特定情況下使用可以大大減少代碼量,使代碼更加清晰易懂,可以有選擇性的使用f-string。
format()是python的一個內(nèi)置函數(shù),其使用頻率不高,語法和str.format()大同小異,可以結(jié)合lambda函數(shù)使用或在其它一些特定情況下使用。
字符串格式化就講到這里,我們下次再見啦~ bye bye


參考
為什么浮點數(shù)在計算機中可能不精確?https://mp.weixin.qq.com/s/3pg1wtsOnFqvmSw13YPVPg
如何在python里面精確四舍五入 https://mp.weixin.qq.com/s/25NMrQtFHUq0A4e4VpzT6Qpython
字符串格式化
https://www.cnblogs.com/songdanlee/p/11105807.html
python官網(wǎng)?
https://docs.python.org/3.8/library/string.html#format-specification-mini-language
推薦閱讀
您看此文用? ?
?分?
?
秒,轉(zhuǎn)發(fā)只需1秒哦

?
?分?
?
秒,轉(zhuǎn)發(fā)只需1秒哦