Day 07 程式結構與流程語法:如果對手太弱太簡單,那不是很爽嗎?(上)
註:本篇文章同步刊載於iT邦幫忙,為鐵人賽之系列文章。
https://ithelp.ithome.com.tw/articles/10240601
先來解答昨天的問題吧!
- 李嚴的是炸鳳尾蝦,劉昴星的是雲龍炸蝦,
如同上一篇所提到的,字典的value是可以是list的! - 按照步驟,前三個問題要取liu-lee, lee-liu, lee & liu,
後面將set加進新的key後再替代回原本shrimp[‘炸鳳尾蝦’]。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| >>> shrimp = {'炸鳳尾蝦':['蝦子','核果','油'],'雲龍炸蝦':['蝦子','核果','油','豆皮','醬汁']}
>>> lee = set(shrimp['炸鳳尾蝦'])
>>> liu = set(shrimp['雲龍炸蝦'])
>>> lee # 所以我說那個醬汁呢?
{'核果', '油', '蝦子'}
>>> liu
{'醬汁', '蝦子', '豆皮', '核果', '油'}
>>> liu-lee
{'豆皮', '醬汁'}
>>> lee-liu # 李嚴沒有多用到的東西
set()
>>> lee & liu # 都用到的材料
{'核果', '油', '蝦子'}
>>> lee.add('蘋果', '洋蔥','醬汁') # set不能夠一次add多個key,除了一個一個加以外,也可以用update()方法。(lee.update(['蘋果', '洋蔥','醬汁']))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() takes exactly one argument (3 given)
>>> lee.add('蘋果')
>>> lee.add('洋蔥')
>>> lee.add('醬汁')
>>> lee
{'洋蔥', '醬汁', '蝦子', '蘋果', '核果', '油'}
>>> lee-liu
{'洋蔥', '蘋果'}
>>> shrimp['炸鳳尾蝦'] = list(lee)
>>> shrimp
{'炸鳳尾蝦': ['洋蔥', '醬汁', '蝦子', '蘋果', '核果', '油'], '雲龍炸蝦': ['蝦子', '核果', '油', '豆皮', '醬汁']}
|
- 按照題目要求一個一個來就可以了,請留意index的初始値是0這點呦!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| >>> lt = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> lt1 = lt[::2]
>>> lt2 = lt[1::2]
>>> lt1, lt2
([1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
>>> lt1.extend(lt2)
>>> lt1
[1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
>>> del lt1[7]
>>> lt1
[1, 3, 5, 7, 9, 2, 4, 8, 10]
>>> del lt1[1]
>>> lt1
[1, 5, 7, 9, 2, 4, 8, 10]
>>> lt1.sort()
>>> lt1
[1, 2, 4, 5, 7, 8, 9, 10]
|
接下來,讓我們來介紹今天的主題:程式結構與流程語法。
在這篇文章中,我們要來介紹一些超級無敵常用的東西,
常用到基本上天天會遇到的那種。
首先是程式結構。
我們應該在前幾篇文章中有提到過,
在Python中當需要執行的東西比較多時,
我們是可以將一整段寫在一個.py檔案裡,
再用python xxx.py 的方式去執行,對吧!
在之後的程式裡,如果程式碼比較多比較複雜,
建議讀者先將程式規劃好打在檔案內,再進行執行,
可以避免打錯造成的一些麻煩。
先來談談註解 ,註解通常使用**「#」的符號,
基本上意味著一行程式碼在這個符號後面的任何東西都不會有影響。
(且只影響該行)
(但是擺在字串內的話就不會有註解的效果,會被當成普通的字元)
通常狀況下,在文字編輯器內將想註解的行框起來,再按Ctrl+/**,
編輯器會自動幫助你將這幾行都註解起來。
如果要多行註解的話,也可以在行的最前面使用’’’ (三個單引號),
註解結束的位置同樣放置’’’。
(但這種註解一般被視為在為函式(後面會提到)打說明文件用的文字,
稱之為文件字串(docstring),
沒特別需求的話,Ctrl+/即可)
1
2
3
4
5
6
7
| '''
a = 10
b = 5
print(a * b)
print("一起從零開始學Python,我知道10 * 5 = " + str(a * b))
# 雖然這行有「#」,但實際起作用是外層造成的
'''
|
如果你有一整行很長的運算或文字,
想要做換行的話,請在換行之前的行尾放上「\」 ,
Python會將這樣延續下去的行都當成同一行解讀。
如果在直譯器的狀態下也適用,
這時候直譯器會顯示「…」,代表這行還沒輸入完。
1
2
3
4
5
| >>> 3+5+7+\
... +11+18+\
... 23\
... +10
77
|
接下來就是所有程式基本上都有的方法:如果(if)
「如果…我就…」這種思維邏輯是日常中很常用到的概念,
Python中也不例外,我們常常需要很多判斷來決定下一步要怎麼走。
語法結構如下:
1
2
3
4
5
6
7
| if 陳述式1:
要做的事情1(可以不只一行)
elif 陳述式2:
要做的事情2(可以不只一行)
...
else:
要做的事情n(可以不只一行)
|
上面的意思是說,當陳述式1的結果是真(True)的的時候,
就做「要做的事情1」,
否則如果(elif, 也就是else if的意思)陳述式2是真的的時候,
就做「要做的事情2」,
可以一直接續,前面的陳述式(statement)一旦先碰到一組是真的時候,
做完要做的事情就離開了,
並不會繼續往下看 。
一直到最後一個else的時候,前面的都不成立,就做「要做的事情n」 。
這個結構底下,你可以選擇使用if, if…elif…else, if…else, if…elif都可以。
(只要順序是if最先,elif其次,else擺最後 即可)
其他語言在框「要做的事情」時,
通常會使用大括號{}來表達開頭和結尾,
這點在Python中有很大的不同!
Python中會在陳述式後面加上一個冒號:來做為分界,
接下來的式子執行到哪裡,並不使用大括號,
而是看縮排的程式碼到哪一行。
(一般縮排是用4個空格 ,盡量不要使用tab或2個空格)
還記得上一篇問題中的炸蝦嗎?
1
2
3
4
5
6
7
| lee = {'核果', '油', '蝦子'}
if '醬汁' not in lee: # 李嚴並沒有做醬汁,所以這個陳述式會是真
print('李嚴')
print('沒醬汁')
else:
print('有醬汁')
print('所以我說那個醬汁呢?') # 這個print並不在else的範圍內!
|
我們執行上面的程式碼的結果應該會得到:
因為最後一行並沒有縮排,所以不會算在else的範圍內,
依舊會被print出來。
在判斷的時候,除了剛剛示範的in,
可以使用其他的比較運算子及布林運算子來計算真假。
比較運算子 有:==(相等,因為一個等號是將右邊的東西指定給左邊), !=(不等於),
<(小於), >(大於), <=(小於等於), >=(大於等於), in…(前者在後者的範圍內)
布林運算子 常用的有:and(且), or(或), not(否定)
1
2
3
4
5
6
7
8
9
10
11
12
| >>> x=24
>>> x>3
True
>>> x<21
False
>>> 12<x<100 # 相當於12 < x and x < 100
True
>>> x == 24
True
>>> lt = [1, 3, 24, 10, 33]
>>> x in lt and not x < 23 # and/or的優先順序比較低,會等左右計算完成才處理,not會將結果反轉
True
|
如果有很多重的判斷的話,
我們也可以將其寫成不同層來處理,
怎麼判斷不同層的方式,一樣是看縮排來決定。
1
2
3
4
5
6
7
8
| x = 24
if x % 2 == 0:
if x % 3 == 0:
print('6的倍數')
else:
print('2的倍數')
else:
print('不是2的倍數')
|
執行完應該會print出’6的倍數’,讀者也可以自行嘗試做出不同的多層if結構。
接著要補充一個很重要的點:
Python在處理判斷時,也可以將單純的資料型態做為判斷的依據,
這時候主要在考慮的,就是這個資料型態是否有存放東西,或者它是0 。
包含False, None(代表沒有東西), 0, 0.0, ‘’(空字串), [], (), {}, set()等,
在做為True/False的判斷中,都會被視為False。
所以例如要判斷一個list是否為空,我們可以這樣寫:
1
2
3
4
5
6
7
| >>> lt = []
>>> if lt:
... print('lt is not empty')
... else:
... print('lt is empty')
...
lt is empty
|
接下來我們來談談迴圈 。
迴圈在Python裡面有兩種:while跟for。
while的語法結構如下。
1
2
3
4
5
| while 陳述式:
xxx
yyy
zzz
...
|
while很簡單,只要這個陳述式是真的 ,就會將下面的程式碼區塊執行一次 ,
做完以後呢?回到while這行,重新判斷一次 ,
如果還是成立,就再做一次;
一直到陳述式不成立,或者我們呼叫一些其他的東西強行跳出,才會離開。
可以用來跳離迴圈的方式名為break ,顧名思義就是強行中止現在所在的迴圈 ,
不繼續往下執行 。
另外有一個功能叫continue ,目的是跳過這次的迴圈 (只跳過這次歐!),
回到while這行 ,依照陳述式的結果決定要不要再繼續執行。
我們下面使用input()方法來示範,它能顯示提示字樣,並接受使用者輸入一段字串存放,
讀者可以自行試試看,是否除非你選擇專家模式,否則完全無法離開迴圈。
1
2
3
4
5
6
7
8
9
| while True: # 使用while True須謹慎,一定要留下可以離開的方法!
mode = input('請問你要選擇什麼模式?1. 簡單模式 2. 困難模式 3. 專家模式 [輸入1, 2, 3] ')
if mode == '3':
print('\n選擇專家模式的難關 帶著我的夥伴 還有我的不平凡')
break
elif mode == '1' or mode == '2': # 簡單來說,其他模式都不給過XD
print('不選難一點的嗎?再給你選一次!\n')
continue # 所以在這邊會直接回到迴圈開始處,因而不會印出下一行
print('請輸入正確的選項!\n')
|
1
2
3
| C:\Users\Desolve>python fromzero.py
請問你要選擇什麼模式?1. 簡單模式 2. 困難模式 3. 專家模式 [輸入1, 2, 3] 5545
請輸入正確的選項!
|
1
2
| 請問你要選擇什麼模式?1. 簡單模式 2. 困難模式 3. 專家模式 [輸入1, 2, 3] 1
不選難一點的嗎?再給你選一次!
|
1
2
| 請問你要選擇什麼模式?1. 簡單模式 2. 困難模式 3. 專家模式 [輸入1, 2, 3] 2
不選難一點的嗎?再給你選一次!
|
1
| 請問你要選擇什麼模式?1. 簡單模式 2. 困難模式 3. 專家模式 [輸入1, 2, 3] 3
|
1
2
| 選擇專家模式的難關 帶著我的夥伴 還有我的不平凡
恭喜你選擇專家模式,加油!
|
在Python中,迴圈還有一個特別的用法,就是可以加else。
1
2
3
4
| while 陳述式:
xxx
else:
ooo
|
當while正常的結束,沒有被break跳出 的話,
離開後就會出來找else的區塊執行。
(讀者可將其想成if else的感覺,
正常離開迴圈就是陳述式結果為false的狀況,所以要走else路線)
反之,當迴圈是被break強行離開時,就不會走到else去了!
舉例來說,我們也可以將上面改成:
1
2
3
4
5
6
7
8
9
10
11
12
| mode = ''
while mode != '3': # 使用者選專家模式才能離開!
mode = input('請問你要選擇什麼模式?1. 簡單模式 2. 困難模式 3. 專家模式 [輸入1, 2, 3] ')
if mode == '3':
print('\n選擇專家模式的難關 帶著我的夥伴 還有我的不平凡')
elif mode == '1' or mode == '2': # 簡單來說,其他模式都不給過XD
print('不選難一點的嗎?再給你選一次!\n')
else:
print('不想玩就算了!\n') # 不想玩的,後續就不繼續給提示
break
else: # 正常離開,表示mode輸入了'3'
print('恭喜你選擇專家模式,加油!')
|
1
2
3
| C:\Users\Desolve>python fromzero.py
請問你要選擇什麼模式?1. 簡單模式 2. 困難模式 3. 專家模式 [輸入1, 2, 3] 1
不選難一點的嗎?再給你選一次!
|
1
2
| 請問你要選擇什麼模式?1. 簡單模式 2. 困難模式 3. 專家模式 [輸入1, 2, 3] 2
不選難一點的嗎?再給你選一次!
|
1
| 請問你要選擇什麼模式?1. 簡單模式 2. 困難模式 3. 專家模式 [輸入1, 2, 3] 3
|
1
2
| 選擇專家模式的難關 帶著我的夥伴 還有我的不平凡
恭喜你選擇專家模式,加油!
|
1
2
3
| C:\Users\Desolve>python fromzero.py
請問你要選擇什麼模式?1. 簡單模式 2. 困難模式 3. 專家模式 [輸入1, 2, 3] 8
不想玩就算了!
|
通常狀況下,我們會將迴圏的過程每一次的執行稱為一次迭代(iteration) 。
有些資料型態可以適合每次從裡面取出一個單位出來,
例如str, list, set, dict, tuple…等,
這時候我們會說這些是可迭代的Python物件。
對於可迭代的東西,我們有另一個for迴圏的模式可以輕鬆處理。
for迴圏的語法結構如下:
1
2
| for xxx in ooo:
(對xxx做事情,比如印出來)
|
舉例來說,我們可以從一個list中一個一個取出當中的element,
並將其印出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| >>> lt = [1, -5, 3, 2, 4, 10, 100]
>>> for num in lt:
... print(num)
...
1
-5
3
2
4
10
100
>>> index = 0 # 也可以用index的方式一個一個拿,不要忘記將index每次加1
>>> while index < len(lt):
... print(lt[index])
... index += 1
...
1
-5
3
2
4
10
100
|
如上篇文章提到的,字典的items()也會產生可迭代的物件,
我們可以按順序用name和ingre(ingredient)來對應它。
1
2
3
4
5
6
| >>> shrimp = {'炸鳳尾蝦':['蝦子','核果','油'],'雲龍炸蝦':['蝦子','核果','油','豆皮','醬汁']}
>>> for name, ingre in shrimp.items():
... print(name, ingre)
...
炸鳳尾蝦 ['蝦子', '核果', '油']
雲龍炸蝦 ['蝦子', '核果', '油', '豆皮', '醬汁']
|
另一方面,break, continue, else在for迴圏的用法和while迴圏的用法是一模一樣的,
讀者可以自行嘗試寫寫看。
提到了for,就不得不提另一個很常用的產生迭代的方式:range()。
range()的用法跟slice很像,都是(start, stop, step);
這當中,start不給的話會從0開始,step預設則是1,
而stop由於不像list有確定的長度,所以是必需要給出的數字。
(同樣請留意stop的位置是不算在內的,這點跟slice相同 )
例如:
1
2
3
4
5
6
7
8
9
10
11
12
| >>> range(7) # 只給一個數字的話是表示stop,所以相當於range(0, 7)
range(0, 7)
>>> list(range(7)) # 可以將其產生為list
[0, 1, 2, 3, 4, 5, 6]
>>> list(range(1, 5))
[1, 2, 3, 4]
>>> list(range(1, 5, -1)) # step走-1並沒有符合的數字
[]
>>> list(range(1, 5, 2))
[1, 3]
>>> list(range(10, -88, -10))
[10, 0, -10, -20, -30, -40, -50, -60, -70, -80]
|
因此,如果我們想要從list中從頭每次相隔2,印出其值,就可以寫成這樣:
1
2
3
4
5
6
7
8
| >>> lt = [1, -5, 3, 2, 4, 10, 100]
>>> for i in range(0, len(lt), 2): # 從index 0開始,每次間隔2,直到len(lt)-1 (因為stop的位置不算)
... print(lt[i])
...
1
3
4
100
|
辛苦啦!今天的內容也相當的多,
同樣請練習一下,可別偷懶呦!
那就明天見啦!
工商時間:
抽獎活動還在繼續累積人數(現在好像沒有人想抽XD)
在Python Taiwan的連結第100篇的文章 底下,
公開分享到你的臉書、按讚該篇文章、並留言告訴我說,
「你最喜歡這一整個系列的哪一篇?為什麼?」或
「除了從LeetCode學演算法系列以外,
你還想要看到關於什麼方向的文章?」
超過20則留言的話 (有完成以上步驟的才算),我們就抽一組
「從Leetcode學演算法|進階篇」+「從Leetcode學演算法|面試篇」
課程的免費兌換券進行贈送!
期限嘛…就延長到滿人數吧XDD (不然也沒辦法哈哈)
容筆者工商一下,
「從Leetcode學演算法|進階篇」 開放預購啦!
這次選了40道難度加深的LeetCode題目,
同樣也會細部解說對應的技巧及須要掌握的演算法!
同時這次購買進階篇的話,
額外還加贈**「從Leetcode學演算法|面試篇」** !
當中包含了面試準備須知分享 ,及訪談國內外不同經驗的工程師 ,
讓你不論是想走前端/後端/一般軟工 或者是想找國外的工作 ,
是初學想轉職 還是正在工作 ,都能夠從中得到收穫呦!
有興趣的朋友可以使用下面的早鳥優惠~
「從Leetcode學演算法|進階篇」+「從Leetcode學演算法|面試篇」 :
https://bit.ly/advleetcode
「從Leetcode學演算法」全套(基礎/進階/面試篇)同捆優惠:
https://bit.ly/allleetcode