iT邦幫忙

2

【python入門教室】(9) python3.6版後的新特性: f-string,方便在字串內放變數

要印出一個字串很簡單,
不過如果字串裡面有變數呢?

這邊我們就要從【Python 超入門】(7) for/while邏輯- 人生苦短,重複的事情就交給程式做吧
兔兔罰抄的故事說起了

範例: 兔兔的罰寫作業一百遍

話說在可愛動物程式學園中,
兔兔因為上課偷睡覺被馬老師抓到,
馬老師決定讓兔兔罰抄「我以後上課不會打瞌睡」一百遍。

馬老師給兔兔兩個選擇,

  1. 用手抄一百遍
  2. 由於是程式學園,改以在螢幕上顯示一百遍「我以後上課不會打瞌睡」

兔兔當然是選擇第二種嘛,
不然手抄會抄到手非常酸的

於是兔兔有了這支程式:

for i in range(100):
    print('我以後上課不會打瞌睡')

<續集>
這時馬老師來檢查兔兔的螢幕,
馬老師說「這樣不行,我怎麼知道螢幕上是不是真的有一百遍文字呢?難道要我一行一行數嗎?」
馬老師要求在每句的「我以後上課不會打瞌睡」前面要加上編號,
在螢幕上要顯示
1. 我以後上課不會打瞌睡
2. 我以後上課不會打瞌睡

100. 我以後上課不會打瞌睡
這樣子才一目瞭然

聰明如你,幫兔兔想想辦法程式要怎麼改寫呢?

方法一、字串的串接

聰明如你當然很快就想到了,
要在「我以後上課不會打瞌睡」前面要加上編號,
那個編號是一個變數,會隨著迴圈運行一直在改變,
因此程式要這樣改寫:

for i in range(1, 101):
    print(str(i)+'. 我以後上課不會打瞌睡')

i是1~100之間的數字,先把它轉成字串,
再跟後面的句字「. 我以後上課不會打瞌睡」用+號串接起來就可以了

然而若是一個字串裡面有多個變數,
可能也會看的頭昏腦脹,
還好python3.6以後的新語法提供了更簡單的寫法

方法二、f-string

如果你的字串裡面要放變數的話,
可以簡單在字串的前面加上一個前綴f
是變數的地方用大括號{}包起來即可,譬如:

for i in range(1, 101):
    print(f'{i}. 我以後上課不會打瞌睡')

這邊i是一個變數,用大括號包起來,
這樣程式就會自動把i的值代入字串裡了

當字串裡面需要很多變數時,
用f-string的寫法便會簡單許多
我們再看一個範例:

範例: 用程式印出九九乘法表

相信小時候大家都有背過九九乘法表吧?

1*1=1, 1*2=2, 1*3=3, …, 1*9=9,
2*1=2, 2*2=4, 2*3=6, …, 2*9=18,
…
9*1=9, 9*2=18,9*3=27, …, 9*9=81

試著用程式印出一份九九乘法表吧。

要直接印出整張九九乘法表似乎不好想,
如果我們只要印出一列呢?例如印出
3*1 到 3*9 的結果:

>>> [3*i for i in range(1,10)]
[3, 6, 9, 12, 15, 18, 21, 24, 27]

很簡單就可以寫出來。
但由於我們希望把整個算式3*1=3 印出來,
而不是只有印出3一個數,
我們需要使用字串前綴f來處理:

>>> [ f"3*{i}={3*i}" for i in range(1,10)]
['3*1=3',
 '3*2=6',
 '3*3=9',
 '3*4=12',
 '3*5=15',
 '3*6=18',
 '3*7=21',
 '3*8=24',
 '3*9=27']

(由於螢幕空間不夠印出一整列,印出來會換行顯示)

既然會印出3*1 到 3*9 的結果了,
那如果改成印4*1 到 4*9 的結果,
也就只是簡單的舉一反三了:
[ f"4*{i}={4*i}" for i in range(1,10)]
也就是說,印出整張九九乘法表,
把原來放3的這個位置用個變數取代就行了。

>>> [[ f"{j}*{i}={j*i}" for i in range(1,10)] for j in range(1,10)]
[['1*1=1',
  '1*2=2',
  '1*3=3',
  '1*4=4',
  '1*5=5',
  '1*6=6',
  '1*7=7',
  '1*8=8',
  '1*9=9'],
 ['2*1=2',
  '2*2=4',
  '2*3=6',
  '2*4=8',
  '2*5=10',
  '2*6=12',
  '2*7=14',
  '2*8=16',
  '2*9=18'],
 ['3*1=3',
  '3*2=6',
  '3*3=9',
  '3*4=12',
  '3*5=15',
  '3*6=18',
  '3*7=21',
  '3*8=24',
  '3*9=27'],
…(中間省略部分結果)
 ['8*1=8',
  '8*2=16',
  '8*3=24',
  '8*4=32',
  '8*5=40',
  '8*6=48',
  '8*7=56',
  '8*8=64',
  '8*9=72'],
 ['9*1=9',
  '9*2=18',
  '9*3=27',
  '9*4=36',
  '9*5=45',
  '9*6=54',
  '9*7=63',
  '9*8=72',
  '9*9=81']]

但是目前是把列表印出來,
並不是很方便閱讀,
我們可以搭配在【python入門教室】(4) 超完整的python字串函數用法統整講解過的' '.join()語法,把列表內字串串起來:

for j in range(1,10):
    print(' '.join([ f"{j}*{i}={j*i}" for i in range(1,10)]))

結果為:

1*1=1 1*2=2 1*3=3 1*4=4 1*5=5 1*6=6 1*7=7 1*8=8 1*9=9 
2*1=2 2*2=4 2*3=6 2*4=8 2*5=10 2*6=12 2*7=14 2*8=16 2*9=18 
3*1=3 3*2=6 3*3=9 3*4=12 3*5=15 3*6=18 3*7=21 3*8=24 3*9=27 
4*1=4 4*2=8 4*3=12 4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36 
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 5*6=30 5*7=35 5*8=40 5*9=45 
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 6*7=42 6*8=48 6*9=54 
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 7*8=56 7*9=63 
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 8*9=72 
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81

但是因為計算結果有的是一位數,有的是兩位數,
這樣印出來沒有對齊,
我們可以把列印的語法改成f"{j}*{i}={j*i:2d}"
在大括號中加入冒號,指定我們想要的格式,
例如{j*i:2d}2d表示把計算的結果當作2位數整數來印
(完整格式運用可參考官方文檔)

修改如下:

for j in range(1,10):
    print(' '.join([ f"{j}*{i}={j*i:2d}" for i in range(1,10)]))

結果為:

1*1= 1 1*2= 2 1*3= 3 1*4= 4 1*5= 5 1*6= 6 1*7= 7 1*8= 8 1*9= 9
2*1= 2 2*2= 4 2*3= 6 2*4= 8 2*5=10 2*6=12 2*7=14 2*8=16 2*9=18
3*1= 3 3*2= 6 3*3= 9 3*4=12 3*5=15 3*6=18 3*7=21 3*8=24 3*9=27
4*1= 4 4*2= 8 4*3=12 4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36
5*1= 5 5*2=10 5*3=15 5*4=20 5*5=25 5*6=30 5*7=35 5*8=40 5*9=45
6*1= 6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 6*7=42 6*8=48 6*9=54
7*1= 7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 7*8=56 7*9=63
8*1= 8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 8*9=72
9*1= 9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81

哇,沒想到短短程式碼竟可以這麼整齊的印出九九乘法表呢,
希望今天的內容也有給讀者收穫

課後練習

  1. 6kyu- Create Phone Number
    題目說明: 給你電話號碼十位數,輸出指定格式的字串
    範例input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
    範例output: "(123) 456-7890"

注意如果這題你打算用f-string來解,python的編譯器需選擇3.6版,
否則可能程式編譯不過
https://ithelp.ithome.com.tw/upload/images/20200411/20117114O53KGQedag.png


1 則留言

1
Pondudu
iT邦新手 5 級 ‧ 2020-04-22 12:30:45

小馬哥安安,我的解答:

def create_phone_number(n):
    return f"({n[0]}{n[1]}{n[2]}) {n[3]}{n[4]}{n[5]}-{n[6]}{n[7]}{n[8]}{n[9]}"

明明就很簡單,不知道為什麼可以卡很久....才發現都把全部元素寫過一遍,我還硬要在後面加上 for n[i] in range(0,9) 怎麼跑都跑不出來哈~

哈囉,謝謝你的分享,大概知道你卡住的點在哪,
你會想說用for i in range(9),
大概是想找簡便的寫法,不想暴力填數字吧,
會想到這一層其實蠻好的

畢竟雖然現在只有十個數字,
但若有外星人有20位數的電話號碼,
格式是(xxxxx) xx-xxx-xxxxx-xxxxx 之類的,
慢慢填數字可能也不是好方法,
不過目前小馬也沒想到太好的方法,
這個疑惑就先留著吧~

Pondudu iT邦新手 5 級 ‧ 2020-04-22 18:43:14 檢舉

對! 被發現了哈哈XDD

在解答區有看到幾個不同的答案,覺得這個可以參考:

def create_phone_number(n):
    n = ''.join(map(str,n))
    return '(%s) %s-%s'%(n[:3], n[3:6], n[6:])

剛好看完小馬哥下一章教的map(),還有之前在time函式提到的%,但看完還是比較喜歡f-string一行解決更直觀~如果是外星電話再用這個/images/emoticon/emoticon37.gif

哦哦~ 這個感覺不錯呢/images/emoticon/emoticon07.gif

我要留言

立即登入留言