iT邦幫忙

3

【python入門教室】(5) 內建型態介紹: 元組tuple(),字典dict(), 集合set()

大家好,我是心原一馬,
python的內建型態有
「整數」(int)、「浮點數」(float)、「字串」(str)、「列表」(list),
「布林值」(bool)、「元組」(tuple)、「集合」(set)、「字典」(dict)
這八種
在【Python 超入門】已介紹過整數、浮點數、字串、列表、布林值五種型態,
今天就要將剩餘三種還沒介紹的內建型態介紹一下啦~

變數型態- tuple: 不能改變內容的百寶袋

要學習tuple,你可以直接在【Python 超入門】(4) 變數型態-list: 能納百物的百寶袋
這一篇複習「變數型態- list: 能納百物的百寶袋」的內容,
因為tuple跟list的語法大概有87%像

宣告一個列表(list)

建立列表(list)時,必須把資料用中括號[]圍起來,用逗號,把資料隔開,
例如我們宣告一個變數pocket表示多啦a夢的口袋,裡面裝著特別的道具:

pocket = ['任意門', '縮小燈', '時光機'] 

宣告一個元組(tuple)

宣告元組的方式跟列表(list)大同小異,只是差在元組改成用小括號

pocket = ('任意門', '縮小燈', '時光機')

這邊需特別注意,如果元組只有唯一一個元素,
宣告時必須在元素後面加上逗號,例如:

pocket = ('任意門', )

除此之外,元組和list的用法幾乎一樣,
譬如說你要取得元素內的資料,
一樣在列表名稱後面加上中括號[]
裡面填入位置編號(一樣請記得編號從0開始數),即可取出資料值,例如:

pocket = ('任意門', '縮小燈', '時光機')
print(pocket[0])
print(pocket[1])
print(pocket[2])
print(pocket[-1]) #取得倒數第一個元素

結果:
任意門
縮小燈
時光機
時光機

你要在元組新增元素,一樣加「+=」即可,如

pocket = ('任意門', '縮小燈', '時光機')
pocket += ('竹蜻蜓',)
print(pocket) #('任意門', '縮小燈', '時光機', '竹蜻蜓')

那麼…元組跟列表差在哪裡?

元組跟列表就一個差別,列表可以改變裡面的元素內容,元組不行
譬如說我有兩個口袋AB,分別宣告成「列表」和「元組」,
我們可以把列表的第一個位置換成「'放大燈'」,
但是對元組做同樣的操作則是錯誤的語法

pocketA = ['任意門', '縮小燈', '時光機'] 
pocketB = ('任意門', '縮小燈', '時光機')
pocketA[1] = '放大燈' # 合法
pocketB[1] = '放大燈' # 錯誤: 元組內元素不可改變

變數型態- dict: 就是查資料的字典

不知道大家小學有沒有查過字典呢?
由於現在網路太發達了,
不一定人人都摸過實體字典,
這邊以線上的教育部國語字典為例(圖示為查詢「字典」這個詞的意思):
https://ithelp.ithome.com.tw/upload/images/20190914/20117114Zk9ebNCcCf.png

當你不知道一個詞語的意思時,
你會輸入關鍵字(key)在字典中查詢,
然後便可以查詢那個詞語的解釋(value)。
這種查詢的概念便類似python的字典(dict),
python的dict由一組key:value組成放在大括號裡,
例如:

D = {'s':"黑桃", 'h':"紅心", 'd':"方塊", 'c':"梅花"}

此時我們便建立了一本字典,
可以想成是「詞語's'的意思為"黑桃"」,「詞語'h'的意思為"紅心"」…。
當我們想要查詢某個字的意思,
便可以用中括號放入關鍵字做查詢,如:

>>> D['s']
'黑桃'
>>> D['d']
'方塊'

其實小馬覺得列表可以想成是一種特別的字典,
只是列表的查詢一定是用「index」(位置)去查,
像是當你寫

pocket = ['任意門', '縮小燈', '時光機'] 
print(pocket[1])

這邊pocket[1]其實就是查說放在列表的第一個位置的元素是什麼

而字典就更廣了,「整數」(int)、「浮點數」(float)、「字串」(str)、「布林值」(bool)、「元組」(tuple)都可以當做是key來查詢(列表不能當key)

變數型態- set: 像是數學上講的集合

至於set是什麼呢?set其實就是數學上講的集合

  • 放在集合裡面的元素順序不重要
  • 放在集合內的元素不會重複
    例如說{1,2,3}{2,3,1}{1,1,2,2,3}指的全部都是同一個集合

其實字典也具有這樣的特性:

  • key值的順序不重要
  • key值不會重複

看幾個例子即可明白,舉例來說我們宣告兩本字典,
裡面的內容都一樣,但是順序對調,
==判斷會將兩本字典視為相同內容(比較: 若是列表與元組的元素順序不同即視為不同)

D1 = {'s':"黑桃", 'h':"紅心", 'd':"方塊", 'c':"梅花"}
D2 = {'d':"方塊", 'c':"梅花", 's':"黑桃", 'h':"紅心"}
print(D1 == D2) # True

另外,若我們宣告下列三個集合,
程式則會判斷這三個集合都是相同的

s1 = {1,2,3}
s2 = {2,3,1}
s3 = {1,1,2,2,3}
print(s1 == s2) # True
print(s2 == s3) # True

python型態之間的轉換

在python中要轉換資料型態,
沒有繁複的語法,
只要把要轉換的資料放進對應的函數裡就行了。
例如有一個字串:

s = "0025"

我們可以轉換成不同型態:

>>> int(s) #轉換成整數
25
>>> float(s) #轉換成浮點數
25.0
>>> list(s) #轉換成列表
['0', '0', '2', '5']
>>> tuple(s) #轉換成元組
('0', '0', '2', '5')
>>> set(s) #轉換成集合
{ '0', '2', '5'}
>>> dict(s) #字串無法直接轉換成字典,會報錯
ValueError

這樣方便的轉換有時會帶來許多好處,
譬如說我想問你一個數字n它是幾位數,(如: 6789是四位數,500是三位數)
如果把n當成是一個數字處理的話恐怕不容易直接回答,
但如果直接轉為字串的話,
只要取字串的長度(用len函數)就知道數字是幾位數了

範例: 求數字位數

n = 123
print(len(str(n)))

經典運用: 用set()去除列表重複的元素

多啦a夢的口袋裡有很有多奇特好用的道具,
但是多啦a夢很迷糊,常常會買到重複的道具,
請你幫它數一數,多啦a夢的口袋(用list)表示總共有幾樣道具呢?

例子:
input: pocket = ['任意門', '縮小燈', '時光機', '縮小燈', '縮小燈', '任意門'] 
output: 3 (總共有「任意門」、「縮小燈」、「時光機」三樣道具)

由於set裡面不會有重複的元素,我們只要將列表轉換成set,
即可去除重複的元素了

pocket = ['任意門', '縮小燈', '時光機', '縮小燈', '縮小燈', '任意門'] 
print(set(pocket)) #印出{'時光機', '縮小燈', '任意門'} (順序不一定)

剩下的就給讀者當課後練習囉~

課後練習

  1. 請完成countItem(pocket)這個函數,pocket表示多啦a夢的口袋,函數回傳口袋有幾樣不重複的道具?
def countItem(pocket):
    return # 這邊寫你的程式碼,只要你文章有讀懂應該很簡單的 >_<
  1. 7kyu- Number of Decimal Digits -CodeWar上的題目,判斷一個數字幾位數
  2. 7kyu- Isograms- 這題可能稍有挑戰性,歡迎留言討論答案。判斷一個字串裡是不是有重複的字元(忽略大小寫的差別)

1 則留言

1
Pondudu
iT邦新手 5 級 ‧ 2020-04-15 01:03:43

小馬哥您好,以下是我的課後練習作業(・ω・):

def countItem(pocket):
    return len(set(pocket))

先轉換成集合排除重複元素,再用len()計算集合的個數,再麻煩您指教!

另外在做第三題7kyu- Isograms-的時候,一開始想法是先全部轉成小寫(或大寫)英文,排除重複項目並轉回字串後,再檢查是否和原字串相同,但失敗後才想到set不會乖乖地按照原本順序排序(☉д⊙),但用sorted()又只能重小到大排,實在不知道怎麼按照原本排序,磨了半小時無解,只好請教估狗大神,發現還真的有辦法XDD

但sorted不能排字串,最後改成用列表比較:

def is_isogram(string):
    string = list(string.lower())
    if string == sorted(set(string),key=string.index):
        return True
    else:
        return False

通過的那一剎真的很爽(❁ω❁)(雖然有作弊)

結果去參考別人答案才發現自己繞了一大圈,完全把第一題的觀念拋到腦後(°ཀ°):

def is_isogram(string):
    return len(string) == len(set(string.lower()))

不知道自己在排什麼啦XDDDDDD

PS: 小馬哥的文章內元組那邊有個小地方寫錯了,宣告一個元組(list),應該是(tuple)~

心原一馬 iT邦研究生 5 級 ‧ 2020-04-15 20:52:31 檢舉

嗨嗨,你的課後練習作業寫的是對的,
然後很開心你跟小馬分享你的解題心路歷程,
希望你有喜歡小馬精選的題目 ^^

心原一馬 iT邦研究生 5 級 ‧ 2020-04-15 22:37:55 檢舉

啊,對了,謝謝你幫小馬找到文章內的筆誤,已於文中修正 ^^

Pondudu iT邦新手 5 級 ‧ 2020-04-16 09:03:55 檢舉

謝謝小馬哥/images/emoticon/emoticon42.gif

我要留言

立即登入留言