φυβλαςのβλογ
บล็อกของ phyblas



การใช้ f-string เพื่อจัดรูปแบบสายอักขระใน python
เขียนเมื่อ 2019/07/14 01:25
แต่เดิมทีเวลาที่ต้องการจัดรูปแบบการแสดงผลของสายอักขระในไพธอนจะใช้รูปแบบการเขียนโดยใช้ % ดังที่ได้เขียนไปใน https://phyblas.hinaboshi.com/tsuchinoko10

รูปแบบการเขียนแบบนี้มีที่มาจากในภาษาซี และถูกใช้อย่างกว้างขวาง สามารถใช้ในภาษารูบีและ php ได้ด้วย

แต่ว่าในไพธอนรุ่น 3.6 เป็นต้นมามีอีกวิธีที่ถูกเพิ่มเข้ามา ซึ่งช่วยให้สะดวกในการเขียน และทำให้เขียนสั้นลงกว่าเดิม วิธีการนั้นเรียกว่า f-string

ในบทความนี้จะพูดถึงวิธีใช้ f-string



การใช้งานเบื้องต้น

การใช้ f-string ทำได้โดยเติม f เปิดไว้ที่ด้านหน้าเครื่องหมายคำพูด แล้วใช้ {} ล้อมส่วนที่ต้องการแทรกค่าลงไป
khong = 'ผัก'
rakha = 100
print(f'ฉันไปตลาดซื้อ{khong} จ่ายไป {rakha} บาท')

ได้
ฉันไปตลาดซื้อผัก จ่ายไป 100 บาท

จะเห็นว่าการใช้นั้นง่ายดาย แค่แทรก {ชื่อตัวแปร} ลงไป

หากวิธีเดิมที่เขียนเป็น % ก็จะเป็นแบบนี้
print('ฉันไปตลาดซื้อ%s จ่ายไป %d บาท'%(khong,rakha))

หรือถ้าใช้การบวกต่อสายอักขระก็จะเป็นแบบนี้
print('ฉันไปตลาดซื้อ'+khong+' จ่ายไป '+str(rakha)+' บาท')

หากเทียบกันแล้ว f-string เขียนสั้นที่สุด

ขอแค่เติม f ไว้ข้างหน้า จะใช้กับเครื่องหมายคำพูดแบบซ้อนสามก็ได้
chue = 'โคอิซึมิ'
ayu = 15
ahan = 'ราเมง'
s = f'''ฉันชื่อ{chue}
อายุ {ayu} ปี
ชอบกิน{ahan}ที่สุด'''
print(s)
ได้
ฉันชื่อโคอิซึมิ
อายุ 15 ปี
ชอบกินราเมงที่สุด

ค่าที่ใส่ใน {} นั้นที่จริงแล้วไม่จำเป็นต้องเป็นตัวแปรเดี่ยวๆก็ได้ อาจใส่ค่าไปโดยตรง หรือใส่ฟังก์ชันคำนวณก็ยังได้
import math
print(f'180 องศาเท่ากับ {math.radians(180)} เรเดียน') # ได้ 180 องศาเท่ากับ 3.141592653589793 เรเดียน
print(f'{19} คูณ {18} เท่ากับ {19*18}') # ได้ 19 คูณ 18 เท่ากับ 342
print(f'อนันต์{math.inf}') # ได้ อนันต์inf

สิ่งที่อยู่ข้างใน {} จะมีการคำนวนหรือการทำงานของฟังก์ชันเหมือนกับเวลาที่อยู่ข้างนอก

แต่ว่าหากต้องการพิมพ์อักษร { หรือ } ในขณะที่ใช้ f-string ไปด้วยนั้น จะต้องเขียน {{ แทน { และเขียน }} แทน } ไม่เช่นนั้นจะเกิดข้อผิดพลาดได้

p = 'พลังคลื่นเต่า'
print(f'{p} {') # ได้ SyntaxError: f-string: expecting '}'
print(f'{p} {{') # ได้ พลังคลื่นเต่า {
print(f'{p} {{{{{{{{') # ได้ พลังคลื่นเต่า {{{{



การเพิ่มความยาวให้จำนวนช่องยาวตามที่กำหนด

หากเติม : แล้วตามด้วยตัวเลขจะเป็นการกำหนดความยาวต่ำสุดของสายอักขระที่ต้องการ โดยมีการเติมช่องว่างมาเสริมให้ยาวเท่ากับที่กำหนด แต่ถ้าเลขที่ใส่ต่ำกว่าความยาวเดิมก็จะไม่มีการเปลี่ยนแปลง

ถ้าหากเป็นข้อมูลตัวเลขจะถูกจัดชิดขวา ถ้าเป็นชนิดสายอักขระจะถูกจัดชิดซ้าย
print(f'=={"สาย":10}==') # ได้ ==สาย       ==
print(f'=={21121:10}==') # ได้ ==     21121==
print(f'=={1.911:8}==') # ได้ ==   1.911==
print(f'=={1.911:3}==') # ได้ ==1.911==

หากไม่ต้องการชิดตามนั้น สามารถกำหนดการจัดตำแหน่งในการเติมช่องว่างได้ตามที่ต้องการ โดยใส่ ^ หรือ < หรือ >
- < จัดชิดซ้าย
- ^ จัดไว้ตรงกลาง
- > จัดชิดขวา

เพียงแต่ว่าถ้าเป็นตัวเลขจะจัดชิดขวาอยู่แล้ว จึงไม่ต้องเติม > ก็ได้ ส่วนสายอักขระจะถูกจัดชิดซ้ายอยู่แล้ว จึงไม่ต้องเติม < ก็ได้ ผลก็ไม่ต่างกัน

ตัวอย่าง
print(f'm{112:<7}x') # ได้ m112    x
print(f'm{112:^7}x') # ได้ m  112  x
print(f'm{112:>7}x') # ได้ m    112x
print(f'm{1112:^7}x') # ได้ m 1112  x

หากใส่อักษรหรือเครื่องหมายอะไรไว้ทางซ้ายของ < ^ > ก็จะหมายถึงว่าให้เติมด้วยอักษรตัวนั้น แทนที่จะเป็นช่องว่างธรรมดา
print(f'~{"ปาด":#^9}~') # ได้ ~###ปาด###~
print(f'~{"ปวด":ฯ<9}~') # ได้ ~ปวดฯฯฯฯฯฯ~
print(f'~{"ปอด":)>9}~') # ได้ ~))))))ปอด~


การเติมเลข 0 ให้ตัวเลข

สำหรับจำนวนตัวเลข หากต้องการเติมเลข 0 ไปทางขวาตามจำนวนที่กำหนดก็ทำได้โดยเขียน :0 ต่อด้วยจำนวนตัวอักษรรวมทั้งหมดขั้นต่ำที่ต้องการ สามารถใช้ <^> เพื่อกำหนดตำแหน่งของ 0 ที่จะเติมได้
print(f'${26:05}$') # ได้ $00026$
print(f'${26:^05}$') # ได้ $02600$
print(f'${26:<05}$') # ได้ $26000$
print(f'${2.6:<05}$') # ได้ $2.600$

ที่จริงแล้วหากใช้วิธีในหัวข้อที่แล้วโดยใส่เลข 0 ไปข้างหน้าก็ได้ผลแบบเดียวกัน
print(f'${27:0>5}$') # ได้ $00027$
print(f'${27:0^5}$') # ได้ $02700$
print(f'${27:0<5}$') # ได้ $27000$

เพียงแต่วิธีการเติม 0 หน้าตัวเลขจำนวนโดยตรงนี้ใช้กับสายอักขระไม่ได้ ถ้าใช้จะเกิดข้อผิดพลาด
print(f'${"หะ":05}$') # ได้ ValueError: '=' alignment not allowed in string format specifier
print(f'${"หะ":0>5}$') # ได้ $000หะ$



การใส่เครื่องหมายบวกให้ค่าบวก

ปกติแล้วตัวเลขที่เป็นลบจะมีเครื่องหมาย - นำหน้า แต่ที่เป็น 0 หรือค่าบวกกลับไม่มีเครื่องหมาย + นำหน้า

เราสามารถกำหนดให้มีการเติมเครื่องหมายบวกนำหน้าเมื่อค่าเป็นบวกได้ โดยเติม :+ ต่อจากตัวเลข

พอทำแบบนี้ค่าบวกก็จะมีเครื่องหมาย + นำหน้า แต่ค่าที่เป็นลบก็จะไม่มีการเปลี่ยนแปลง
print(f'{10:+}') # ได้ +10
print(f'{-10:+}') # ได้ -10

หรือถ้าหากต้องการให้เป็นการเพิ่มช่องว่างแทนที่จะเป็นเครื่องหมายบวก ก็ทำได้โดยใส่ : แล้วตามด้วยช่องว่าง
print(f'a{10: }') # ได้ a 10
print(f'a{-10: }') # ได้ a-10

การทำแบบนี้มีประโยชน์ตรงที่ทำให้จำนวนอักษรของค่าบวกและลบเท่าเทียมกัน

หากต้องการทั้งเติม + ไปด้วยแล้วเติม 0 ไปด้วยก็ให้เติม + ก่อน แล้วค่อยเขียนส่วนกำหนดจำนวน 0 ต่อ
print(f'{17:+08}') # ได้ +0000017


การจัดการเลขทศนิยม

หากเติม :f ต่อท้ายจำนวนตัวเลข จะเป็นการแสดงผลในรูปของจำนวนจริงที่มีทศนิยม ๖ ตำแหน่ง
print(f'{20:f}') # ได้ 20.000000

ถ้าอยากกำหนดเลขหลังจุดทศนิยมตามที่ต้องการให้ใส่ :.จำนวนทศนิยมf
print(f'{20:.2f}') # ได้ 20.00
print(f'{3.4567:.2f}') # ได้ 3.46

สามารถกำหนดการเติมเลข 0 ไปด้วยในเวลาเดียวกันโดยเติมตัวเลือกนี้แทรกระหว่าง : และ .
print(f'{3.4567:09.2f}') # ได้ 000003.46

สามารถใช้ F พิมพ์ใหญ่แทน f ได้ ผลก็เหมือนกัน แต่ข้อแตกต่างจะเกิดขึ้นเฉพาะเวลาที่เจอค่า inf หรือ nan จะถูกพิมพ์ด้วยพิมพ์ใหญ่แทนพิมพ์เล็ก
import math
print(f'{math.inf:09f}') # ได้ 000000inf
print(f'{math.inf:09F}') # ได้ 000000INF
print(f'{math.nan:09f}') # ได้ 000000nan
print(f'{math.nan:09F}') # ได้ 000000NAN


การแสดงผลเลขทศนิยมในรูปคูณ 10 ยกกำลัง

ตัวเลขที่มีค่ามากหลายล้านหรือน้อยแค่หนึ่งส่วนล้านปกติแล้วก็อาจแสดงในรูปของ E จะง่ายกว่า เช่น 1100000 เป็น 1.1

วิธีการคล้ายกับการแสดงเลขทศนิยมธรรมดา แต่เปลี่ยจาก f เป็น e แต่ถ้าต้องการให้เป็น E พิมพ์ใหญ่ก็ใช้ E
print(f'{0.001234:.2e}') # ได้ 1.23e-03
print(f'{0.001234:011.2e}') # ได้ 0001.23e-03
print(f'{0.001234:011.2E}') # ได้ 0001.23E-03

ถ้าใช้ g หรือ G รูปแบบแสดงผลจะถูกกำหนดโดยอัตโนมัติว่าจะแสดงในรูปทศนิยมธรรมดาหรือในรูปคูณ 10 ยกกำลัง ขึ้นกับค่า
print(f'{1230000:g}') # ได้ 1.23e+06
print(f'{123000:g}') # ได้ 123000
print(f'{12.3:g}') # ได้12.3
print(f'{0.000123:g}') # ได้ 0.000123
print(f'{0.0000123:g}') # ได้ 1.23e-05
print(f'{0.00000123:G}') # ได้ 1.23E-06


การแสดงผลจำนวนเป็นร้อยละ

ถ้าเขียนต่อจากตัวเลขด้วย :% ค่าที่ได้จะคูณ 100 แล้วมีคำว่า % ต่อท้าย
print(f'{0.99:%}') # ได้ 99.000000%

ปกติจะมาพร้อมกับเลขทศนิยม ๖ ตำแหน่ง แต่สามารถเติม . เพื่อระบุตำแหน่งเลขทศนิยมที่ต้องการได้เช่นเดียวกับ f หรือ e
print(f'{0.98:.3%}') # ได้ 98.000%
print(f'{0.97:09.2%}') # ได้ 00097.00%


เลขฐาน 2 ฐาน 8 ฐาน 16

ถ้าเติม :b จะเป็นการแปลงค่าเป็นเลขฐาน 2 ถ้าเติม :o จะแปลงเป็นฐาน 8 ถ้าเติม :x หรือ :X จะแปลงเป็นเลขฐาน 16

ข้อแตกต่างประหว่าว x กับ X ก็คือเวลาที่แทนตัวเลข 10 ถึง 15 ถ้าเป็น x จะใช้พิมพ์เล็ก a~f ถ้า X จะใช้พิมพ์ใหญ่ A~F

ตัวอย่าง
print(f'{11:@>10b}') # ได้ @@@@@@1011
print(f'{99:!>11o}') # ได้ !!!!!!!!143
print(f'{254:$<5x}') # ได้ fe$$$
print(f'{254:$^5X}') # ได้ $FE$$

หากเติม # ไปด้านหน้า b หรือ o หรือ x จะแสดง 0b หรือ 0o หรือ 0x เข้ามาด้านหน้า
print(f'{115:#b}') # ได้ 0b1110011
print(f'{777:#07o}') # ได้ 0o01411
print(f'{2241:#08x}') # ได้ 0x0008c1
print(f'~{2243:#8X}') # ได้ ~   0X8C3


การใส่ , หรือ _ แทรกระหว่างตัวเลข

เวลาเขียนตัวเลขยาวๆ บางครั้งเพื่อความเข้าใจง่ายบางคนก็ชอบใช้ , หรือ _ มากั้นทีละ ๓ ตัว

สามารถทำให้เป็นแบบนั้นได้โดยเติม :, หรือ :_

ตัวอย่าง
print(f'{1000000.0:,}') # ได้ 1,000,000.0
print(f'{123456789:_}') # ได้ 123_456_789.0

แต่ว่ารูปแบบนี้ใช้ได้แค่กับ , และ _ เท่านั้น หากจะใช้ตัวอื่นก็ต้องแทนที่เข้าไปเอง เช่นทำแบบนี้
print(f'{10000000000:,}'.replace(',','`')) # ได้ 10`000`000`000



ใช้กับ datetime

f-string ยังสะดวกเวลาที่ใช้กับข้อมูลวันเวลา datetime ด้วย

รายละเอียดเรื่อง datetime อ่านได้ใน https://phyblas.hinaboshi.com/20160621

ในออบเจ็กต์ datetime จะมีเมธอด strptime เอาไว้แสดงผลวันเวลาตามรูปแบบที่กำหนด

หากใช้ f-string สามารถเขียนรูปแบบการแสดงผล datetime ได้โดยตรงโดยไม่ต้องเรียกใช้ strptime เอง

ตัวอย่าง
wanwela = datetime.datetime(2019,7,14,1,25,19)
print(f'{wanwela:เวลา %H:%M:%S วันที่ %d เดือน %0m ปี %Y}') # ได้ เวลา 01:25:19 วันที่ 14 เดือน 07 ปี 2019

ความหมายของพวก %S %m %Y ฯลฯ มีเขียนไว้แล้วในบทความเรื่อง datetime







สรุปส่งท้าย

จะเห็นว่าข้อดีของวิธีนี้คือมีความสามารถมากกว่าแบบเดิมที่ใช้ % และยังเขียนสั้นลงด้วย

เพียงแต่ว่าการทำงานโดยรวมอาจจะช้ากว่าเล็กน้อย รายละเอียดเรื่องนี้ได้เคยศึกษาเปรียบเทียบแล้วเขียนไว้ใน https://phyblas.hinaboshi.com/20190713

อีกทั้งเนื่องจากเพิ่งใช้ได้ตั้งแต่เวอร์ชัน 3.6 ทำให้หากต้องการเขียนโปรแกรมที่รองรับรุ่นเก่าได้ก็จะยังไม่ควรใช้ f-string อยู่ดี ดังนั้นกว่า f-string จะเป็นที่ใช้กันแพร่หลายทั่วไปได้คงต้องใช้เวลา



อ้างอิง


-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
python
-- numpy
-- matplotlib

-- pandas
-- pytorch
maya
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
javascript
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
เรียนภาษาจีน
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  ค้นหาบทความ

  บทความแนะนำ

เรียนรู้วิธีการใช้ regular expression (regex)
หลักการเขียนทับศัพท์ภาษาจีนกวางตุ้ง
การใช้ unix shell เบื้องต้น ใน linux และ mac
หลักการเขียนทับศัพท์ภาษาจีนกลาง
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
บันทึกการเที่ยวสวีเดน 1-12 พ.ค. 2014
แนะนำองค์การวิจัยและพัฒนาการสำรวจอวกาศญี่ปุ่น (JAXA)
เล่าประสบการณ์ค่ายอบรมวิชาการทางดาราศาสตร์โดยโซวเคนได 10 - 16 พ.ย. 2013
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
บันทึกการเที่ยวญี่ปุ่นครั้งแรกในชีวิต - ทุกอย่างเริ่มต้นที่สนามบินนานาชาติคันไซ
หลักการเขียนทับศัพท์ภาษาญี่ปุ่น
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ
ทำไมถึงอยากมาเรียนต่อนอก
เหตุผลอะไรที่ต้องใช้ภาษาวิบัติ?

ไทย

日本語

中文