Skip to main content

Command Palette

Search for a command to run...

從零開始學Python (6) — 從零開始學Python — 串列(list)、Tuple(元組)、字典(dict)、集合(set):我的字典裡沒有放棄,因為我還沒有寫進去(下)

Updated
3 min readView as Markdown

註:本篇文章同步刊載於iT邦幫忙,為鐵人賽之系列文章。
https://ithelp.ithome.com.tw/articles/10240088/

接下來我們要介紹另外兩個資料型態:字典(dict)與集合(set)。
首先是字典:
字典跟串列有點類似的部分,
但是它的表示方式是一個鍵(key)對一個值(value),
就好像函式一樣,一個字典裡面不會出現重覆的key,
但有可能不同key對應的value剛好一樣;
這樣一來,我們就可以用key去查找其對應的value。
需要注意的是,串列是有一個固定的順序排列的,
但字典並不會有固定排序(也就是說一般我們不在意排的順序)。

key和value可以是各種不同的型態如str, int, float, bool等等,
但是key必須要是hashable的資料型態(像list就不是hashable),
value做為被對應的對象,則沒有這種限制。

字典的建立方式,可以用dict()方法,也可以用大括號{},
當中每個key和value的對應使用冒號:來分隔,
而每組key:value之間,使用逗號來分開。
同時,要取得某個key對應的value值,
就像list是用index來取得對應位置的値,字典則使用dict[key]來取得。

>>> dic0 = dict()>>> dic0{}>>> dic = {'xd': 1, '放棄': False, [1,5,9]: 3}  # list是unhashable,不能作為keyTraceback (most recent call last):  File "<stdin>", line 1, in <module>TypeError: unhashable type: 'list'>>> dic = {'xd': 1, '放棄': False, 3.33: 3} # 這樣就沒問題啦!>>> dic{'xd': 1, '放棄': False, 3.33: 3}>>> dic['XD'] # 在程式語言的世界裡,通常大小寫是當作不一樣的呦!Traceback (most recent call last):  File "<stdin>", line 1, in <module>KeyError: 'XD'>>> dic['xd'] # 取值1>>> dic['放棄']False>>> dic[3.33]3

上篇提到list()可以拿來轉換,dict()也有類似的特異功能,
只要內容是剛好每一組都是兩項的就可以了!
(串列/tuple/剛好兩個字元的字串…)
我們看一下範例:

>>> lol = [('易大師','我的劍,就是你的劍。'),('犽宿','死亡如風,常伴吾身。'),('阿祈爾','蘇瑞瑪!你的王已經歸來了!')]>>> diclol = dict(lol)>>> diclol{'易大師': '我的劍,就是你的劍。', '犽宿': '死亡如風,常伴吾身。', '阿祈爾': '蘇瑞瑪!你的王已經歸來了!'}>>> tul = (['a','b'],['c','d'],['e','f'],['g','h']) # 裡外兩層不管是tuple或list都沒有問題!>>> dictul = dict(tul)>>> dictul{'a': 'b', 'c': 'd', 'e': 'f', 'g': 'h'}>>> chs = ['ab','cd','13'] # 兩個字元的字串會被拆開用(但超過兩個字元就不支援了)>>> dicchs = dict(chs)>>> dicchs{'a': 'b', 'c': 'd', '1': '3'}

我們可以使用類似list的方式來對字典插入或修改某個key對應的value值,
如果該key已經存在在字典,則對應的value會被覆蓋,否則就產生一個新的對應。

>>> diclol['伊澤瑞爾'] = '是時候展現真正的技術了!' # 新增>>> diclol{'易大師': '我的劍,就是你的劍。', '犽宿': '死亡如風,常伴吾身。', '阿祈爾': '蘇瑞瑪!你的王已經歸來了!', '伊澤瑞爾': '是時候展現真正的技術了!'}>>> dicchs{'a': 'b', 'c': 'd', '1': '3'}>>> dicchs['a']='XD' # 修改>>> dicchs{'a': 'XD', 'c': 'd', '1': '3'}

接下來是一些常見的dict操作方法,同樣請多加練習,
讀者可能會發現很多會跟list的操作概念相同,所以可以的話,請對照著比較一下。
dict1.update(dict2) -> 將dict2的內容複製後放到dict1(key重覆時,dict2的value優先)。
del dict1[‘key’] -> 將dict1的**’key’:’value’的對應從dict1中刪去**。
dict1.clear() -> 清空整個dict1的對應(也可以用dict1 = dict())。
‘XXX’ in dict1 -> 檢查dict1是否有’XXX’這個key。
dict1.keys() -> 給出整個dict1的所有key(如果需要用list的形式表達,請用list()將其框住)。
dict1.values() -> 同上,但給出的是所有value

dict1.items() -> 給出一個一個的key:value對應(每對都以tuple形式給出)。
dict2 = dict1.copy() -> 複製一份dict1的內容,生成一個dict2的字典。
(註:如果是用dict2 = dict1,只會讓兩者共用一個字典,修改會動到同一個呦!)

我們來看一下範例:

>>> diclol['國動'] = '社 社 社社社 社社 社會搖'>>> diclol # 前面建立的字典{'易大師': '我的劍,就是你的劍。', '犽宿': '死亡如風,常伴吾身。', '阿祈爾': '蘇瑞瑪!你的王已經歸來了!', '伊澤瑞爾': '是時候展現真正的技術了!', '國動': '社 社 社社社 社社 社會搖'}>>> diclol['國動'] = '社 社 社社社 社社 社會搖'>>> diclolfame = {'國動':'還敢下來阿冰鳥!', '統神':'他的手怎麼可以穿過我的叭叭啊!'}>>> diclol.update(diclolfame) # 合併過去,重覆的會被覆蓋>>> diclol{'易大師': '我的劍,就是你的劍。', '犽宿': '死亡如風,常伴吾身。', '阿祈爾': '蘇瑞瑪!你的王已經歸來了!', '伊澤瑞爾': '是時候展現真正的技術了!', '國動': '還敢下來阿冰鳥!', '統神': '他的手怎麼可以穿過我的叭叭啊!'}>>> del diclol['統神'] # 刪除對應的鍵值對>>> diclol{'易大師': '我的劍,就是你的劍。', '犽宿': '死亡如風,常伴吾身。', '阿祈爾': '蘇瑞瑪!你的王已經歸來了!', '伊澤瑞爾': '是時候展現真正的技術了!', '國動': '還敢下來阿冰鳥!'}>>> dicchs = {'a': 123, 'c': 428, '1': '3', 'eee': 11}>>> dicchs{'a': 123, 'c': 428, '1': '3', 'eee': 11}>>> dicchs.clear() # 清空字典>>> dicchs{}>>>>>> '統神' in diclolfameTrue>>> '統神' in diclol # 我們剛剛刪除了,所以'統神'不會在diclol裡False>>> dicn = {'a': 1, 'b': 2, 'c': 3, 'd': 4}>>> dicn{'a': 1, 'b': 2, 'c': 3, 'd': 4}>>> dicn.keys() # 取得keydict_keys(['a', 'b', 'c', 'd'])>>> list(dicn.keys()) # 如果需要list型式的話就外面加一層list()['a', 'b', 'c', 'd']>>> dicn.values()dict_values([1, 2, 3, 4])>>> dicn.items()dict_items([('a', 1), ('b', 2), ('c', 3), ('d', 4)])>>> dico = dicn # 直接用等號,在字典相當於貼標籤在同一個身上>>> dico['a'] = 'XD'>>> dico{'a': 'XD', 'b': 2, 'c': 3, 'd': 4}>>> dicn # 結果原先的也一起被改到了!{'a': 'XD', 'b': 2, 'c': 3, 'd': 4}>>> dico = dicn.copy() # 使用copy()來處理>>> dico['a'] = 1>>> dico{'a': 1, 'b': 2, 'c': 3, 'd': 4}>>> dicn # 這樣dico和dicn就是兩個不一樣的字典囉!{'a': 'XD', 'b': 2, 'c': 3, 'd': 4}

(註:在其他語言裡,通常把key:value對應的資料結構稱作hash或hash map)

接下來要講的是集合(set)。
集合不像字典,它的本身只有key而已,
每個key都必須不重覆(就像數學學到的那樣)
要建立的方式,可以使用set(),或者使用大括號{},
當中每個key之間使用逗號連接,要增加key則使用add()。
(同樣用大括號,集合沒有value對應的部份)
集合本身也是不講求排列順序的,這點和字典一樣。

>>> st = set()>> st # 因為空的大括號代表字典,所以要產生一個空集合只能使用set(),不能用{}set()>>> st.add(3)>>> st{3}>>> st.add(3) # 重覆的增加相同的key不會對set造成影響>>> st{3}>>> st.add('XD') # set中的key不一定要有相同的資料型態>>> st{'XD', 3}>>> set('XDDDD') # 可以拿單一字串放入,會被拆開來看待(重覆的被刪去){'D', 'X'}>>> set(['XDDDD','XD','XD','XDDD']) # list則會以元素為單位,此外,留意它並沒有順序。{'XD', 'XDDDD', 'XDDD'}>>> st1 = {'A', 'C', 'E'}>>> st2 = {'B', 'C', 'A', 'D'}>>> 'A' in st1 # 集合同樣也可以用in來檢查是否存在keyTrue>>> 'e' in st1False

既然是集合,可想而知就會有許多跟數學上集合對應的操作,
我們就直接來看範例:

>>> st1 & st2 # '&'(念作and, 代表'且',也就是兩者皆有才算有)和intersection都是取交集{'C', 'A'}>>> st1.intersection(st2){'C', 'A'}>>> st1 | st2 # '|'(念作or, 代表'或',也就是兩者之一有就可以了)和union都是取聯集{'A', 'D', 'E', 'C', 'B'}>>> st1.union(st2){'A', 'D', 'E', 'C', 'B'}>>> st1 - st2 # '-'和difference都是取差集,也就是取前者有,後者沒有{'E'}>>> st2 - st1{'D', 'B'}>>> st1.difference(st2){'E'}>>> st1 ^ st2 # '^'(念作exclusive or, 代表'互斥或',也就是只能其中一個有,另一個沒有的)和symmetric_difference(太長啦!不用記XD)都是取互斥或{'B', 'D', 'E'}>>> st1.symmetric_difference(st2){'B', 'D', 'E'}>>> st1 <= st2 # '<='和issubset代表檢查前者是否是後者的子集False>>> st2 <= st1False>>> st1.issubset(st2)False

其他還有一些,但有需要用到時再查對應功能即可。

最後一樣來做個練習吧!

  1. 眾所周知,李嚴和劉昴星曾經比過炸龍蝦,
    請建立一個字典名為shrimp,當中
    請使用兩者的作品的名字做為key
    將其做的炸蝦所使用到的材料/內容列表list做為value
    還未做完成的部分不算。請參考原本對於兩人作品的描述如下:

李嚴的作品:「我的料理是炸鳳尾蝦,就是蝦子裹碎核果去炸的,將核果搗碎後裹在蝦肉上,炸成為金黃色,不但要考慮核果跟蝦肉的比例,高低油溫的調節也需要高度的技術跟經驗的。鮮脆可口的核果外衣,經油炸之後,其香味立即倍增,堪稱人間第一美味,搭配特製醬汁來食用,味道更是妙不可言。跟醬汁巧妙的組合,這是這個炸蝦的精華所在。那個醬汁,那要先將蘋果,洋蔥等切成末之後,跟各種調味料以絕妙的比例互相調合。那個醬汁,再給我一分鐘我一定能完成的!」

劉昴星的作品:「炸的香酥的核果外衣,蝦肉(蝦子)的甘甜,與順滑可口的醬汁搭配起來,真是太棒了……我在蝦肉和外衣之間,夾了豆皮封住醬汁,如此一來,就算在油鍋裡炸,醬汁也一定不會流出來。裹著一層豆皮雲的龍蝦,名字叫做小當家特製雲龍炸蝦!」

2. 承1,請將兩人的材料從shrimp中取出,
分別放入兩個set中,並命名為’lee’跟’liu’。
請利用set的操作,回答以下問題:
劉昴星的作品中比李嚴的作品多用了什麼材料?
李嚴的作品中比劉昴星的作品多用了什麼材料?
兩人的作品都有用到什麼材料?
假定今天李嚴能做完醬汁的話,請將新增的材料(蘋果、洋蔥)以及內容(醬汁),
加到lee這個set中,
接著請指出現在李嚴的作品中比劉昴星的作品多用了什麼材料?
並請將材料和內容更新回shrimp這個字典中的對應作品。

3. 已知有一個列表lt = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
請利用slice及其他方法來達成以下要求:
a. 請生成一個lt1,其內容為lt的所有奇數
b. 請生成一個lt2,其內容為lt的所有偶數
c. 請將lt2的所有元素依序附加到lt1上
d. 請刪除lt1當中index 7和index 1的數
e. 請將lt1進行排序

辛苦了,這兩篇對於初學者來說應該很長,
但很基本,請多加嘗試練習,
後續使用到對應用法如果還是忘記的話,
可以再回頭看著對照。
那就明天見囉!

**工商時間:
**抽獎活動還在繼續累積人數(現在好像沒有人想抽XD)
Python Taiwan的連結第100篇的文章底下,
公開分享到你的臉書、按讚該篇文章、並留言告訴我說,
「你最喜歡這一整個系列的哪一篇?為什麼?」或
「除了從LeetCode學演算法系列以外,
你還想要看到關於什麼方向的文章?」

超過20則留言的話(有完成以上步驟的才算),我們就抽一組
「從Leetcode學演算法|進階篇」+「從Leetcode學演算法|面試篇」
課程的免費兌換券進行贈送!

期限嘛…就延長到滿人數吧XDD (不然也沒辦法哈哈)

容筆者工商一下,
「從Leetcode學演算法|進階篇」開放預購啦!
這次選了40道難度加深的LeetCode題目,
同樣也會細部解說對應的技巧及須要掌握的演算法!
同時這次購買進階篇的話,
額外還加贈「從Leetcode學演算法|面試篇」

當中包含了面試準備須知分享及訪談國內外不同經驗的工程師
讓你不論是想走前端/後端/一般軟工或者是想找國外的工作
初學想轉職還是正在工作,都能夠從中得到收穫呦!
有興趣的朋友可以使用下面的早鳥優惠~
「從Leetcode學演算法|進階篇」+「從Leetcode學演算法|面試篇」
https://bit.ly/advleetcode

「從Leetcode學演算法」全套(基礎/進階/面試篇)同捆優惠:
https://bit.ly/allleetcode

請幫我隨手點開下面的SHOW EMBED並按5個like~
喜歡的話也可以幫我拍拍手~
(按讚不用錢,感謝支持寫作~)

More from this blog

是的,估計是需要針對留言點reply才會通知,

是的,估計是需要針對留言點reply才會通知, 我前一個留言說明是回在文章底下,它可能沒有被Medium視為同一串留言的回應, 所以最近我嘗試點reply在您前面的留言留了一份同樣的內容, 看來需要這樣才會通知到。 不好意思,我以後會再注意表達的方式避免有不同解讀造成誤會。 同時再次跟所有讀者說明,個人除非是特殊狀況需求, 否則不會沒事點開任何人的github,甚或對coding style進行評論; 因此,當回應或文章中提到任何推薦使用的工具, 或可以協助改善生產力的東東, 基本都是筆者個人覺...

Apr 4, 20251 min read

(限時)活動分享-Bybit Lauchpool PIRATE

白挖的加密貨幣,不香嗎? 寫在前面:(基礎+進階+面試篇)從 LeetCode 學演算法 + 面試成功指南 (3990元 長期有效) https://bit.ly/lc2022all 容筆者工商一下,「從Leetcode學演算法|進階篇」這次選了40道難度加深的LeetCode題目,同樣也會細部解說對應的技巧及須要掌握的演算法!同時這次購買進階篇的話,額外還加贈「從Leetcode學演算法|面試篇」!當中包含了面試準備須知分享,及訪談國內外不同經驗的工程師,讓你不論是想走前端/後端/一般軟工或者...

Jun 16, 20241 min read
(限時)活動分享-Bybit Lauchpool PIRATE

跟著Desolve學程式

227 posts