Python程式設計

Lesson 7: 元組(Tuple)、字典(Dict)、集合(Set)

資料儲存型別 (3/3)

Python 的4種資料儲存型別

內含多個項目

可修改

內含多個項目

不可修改

元組

內含多個內容相異的項目

無先後次序

內含多個key-value對

可修改

有先後次序

串列複習重點

for迴圈讀取串列

串列所屬各種函式的運用

練習:

撰寫一程式,輸入並建立一組串列,當輸入-999時則輸入結束。請將此串列內容由小到大排序,最後印出排序前、後的串列內容

元組 Tuple

  • 不能修改的串列
串列 = [元素1, 元素2,....] # 以方括弧定義
元組 = (元素1, 元素2,....) # 以小括弧定義

元組Tuple(1/13)

tuple0 = ()                # 空元組
tuple1 = (1,2,3,4,5,6)     # 相同型別
tuple2 = (1, "張三", True) # 不同型別

元組(Tuple):不能修改內容的串列

  • 不能修改:個數、元素值

元組: 使用小括弧

元組 = (元素1, 元素2,....) 
tuple1 = (1,2,3,4,5,6)  # 元素0~5
print(tuple1[3])        # 印出4
tuple1[1] = 100         # 錯誤, 不能修改元素值

範例

元組的優點:

  • 執行速度比串列快
  • 內容無法改變,資料較為安全

元組Tuple(2/13)

# ch8_1.py
numbers1 = (1, 2, 3, 4, 5)      # 定義元組元素是整數
fruits = ('apple', 'orange')    # 定義元組元素是字串
mixed = ('James', 50)           # 定義元組元素是不同型態資料
val_tuple = (10,)               # 只有一個元素的元組
print(numbers1)
print(fruits)
print(mixed)
print(val_tuple)
# 列出元組資料型態
print("元組mixed資料型態是: ",type(mixed))

範例:定義與列印元組,最後使用type()印出資料型態

(1, 2, 3, 4, 5)
('apple', 'orange')
('James', 50)
(10,)
元組mixed資料型態是:  <class 'tuple'>

執行結果

只有一個元素,仍須逗點

元組Tuple讀取元素(3/13)

# ch8_2.py
numbers1 = (1, 2, 3, 4, 5)      # 定義元組元素是整數
fruits = ('apple', 'orange')    # 定義元組元素是字串
val_tuple = (10,)               # 只有一個元素的元祖
print(numbers1[0])              # 以中括號索引值讀取元素內容
print(numbers1[4])
print(fruits[0])
print(fruits[1])
print(val_tuple[0])

讀取元組元素使用方括弧(與讀取串列元素相同): []

1
5
apple
orange
10

執行結果

只有一個元素,仍須逗點

元組Tuple迴圈應用(4/13)

# ch8_3.py
keys = ('magic', 'xaab', 9099)      # 定義元組元素是字串與數字
for key in keys:
    print(key)

for迴圈列出所有元素內容

magic
xaab
9099

執行結果

元組Tuple修改元素內容(5/13)

# ch8_4.py
fruits = ('apple', 'orange')        # 定義元組元素是字串
print(fruits[0])                    # 列印元組fruits[0]
fruits[0] = 'watermelon'            # 將元素內容改為watermelon
print(fruits[0])                    # 列印元組fruits[0]

修改元素內容將會產生TypeError

apple
Traceback (most recent call last):
  File "/Users/leo/Python/ch8/ch8-1.py", line 4, in <module>
    fruits[0] = 'watermelon'            # 將元素內容改為watermelon
TypeError: 'tuple' object does not support item assignment

執行結果

元組Tuple修改元素內容(6/13)

# ch8_5.py
fruits = ('apple', 'orange')        # 定義元組元素是水果
print("原始fruits元組元素")
for fruit in fruits:
    print(fruit)

fruits = ('watermelon', 'grape')    # 定義新的元組元素
print("\n新的fruits元組元素")
for fruit in fruits:
    print(fruit)

修改元素內容?只能重新設定內容

原始fruits元組元素
apple
orange

新的fruits元組元素
watermelon
grape

執行結果

元組Tuple內容切片(7/13)

# ch8_6.py     
fruits = ('apple', 'orange', 'banana', 'watermelon', 'grape')
print(fruits[1:3])
print(fruits[:2])
print(fruits[1:])
print(fruits[-2:])
print(fruits[0:5:2])

內容切片:[起始位置, 結束位置-1, 間隔值]

(起始位置預設值為0,間隔值預設值為1)

('orange', 'banana')
('apple', 'orange')
('orange', 'banana', 'watermelon', 'grape')
('watermelon', 'grape')
('apple', 'banana', 'grape')

執行結果

元組Tuple len()函數(8/13)

# ch8_7.py
keys = ('magic', 'xaab', 9099)      # 定義元組元素是字串與數字
print("keys元組長度是 %d " % len(keys))

len()函數: 取得元組內含元素個數

keys元組長度是 3

執行結果

元組Tuple tuple(), list()函數(9/13)

# ch8_10.py
keys = ('magic', 'xaab', 9099)      # 定義元組元素是字串與數字
list_keys = list(keys)              # 將元組改為串列
list_keys.append('secret')          # 增加元素
print("列印元組", keys)
print("列印串列", list_keys)

tuple(串列): 將串列轉為元組

list(元組)函數: 將元組轉為串列

列印元組 ('magic', 'xaab', 9099)
列印串列 ['magic', 'xaab', 9099, 'secret']

執行結果

元組Tuple max(), min()函數(10/13)

# ch8_12.py
tup = (1, 3, 5, 7, 9)
print("tup最大值是", max(tup))
print("tup最小值是", min(tup))

max(元組): 獲得元組中最大值

min(元組): 獲得元組中最小值

tup最大值是 9
tup最小值是 1

執行結果

元組Tuple enumerate()函數(11/13)

# ch8_13.py
drinks = ("coffee", "tea", "wine")
enumerate_drinks = enumerate(drinks)                # 數值初始是0
print("轉成元組輸出, 初始值是 0 = ", tuple(enumerate_drinks))

enumerate_drinks = enumerate(drinks, start = 10)    # 數值初始是10
print("轉成元組輸出, 初始值是10 = ", tuple(enumerate_drinks))

enumerate(元組): 產生(計數值,元素)配對的新元組

轉成元組輸出, 初始值是 0 =  ((0, 'coffee'), (1, 'tea'), (2, 'wine'))
轉成元組輸出, 初始值是10 =  ((10, 'coffee'), (11, 'tea'), (12, 'wine'))

執行結果

元組Tuple zip()函數(12/13)

# ch8_15.py
fields = ['Name', 'Age', 'Hometown']
info = ['Peter', '30', 'Chicago']
zipData = zip(fields, info)         # 執行zip
print(type(zipData))                # 列印zip資料類型
player = list(zipData)              # 將zip資料轉成串列
print(player)                       # 列印串列

zip(): 將兩個元組或串列合成為一新元組

<class 'zip'>
[('Name', 'Peter'), ('Age', '30'), ('Hometown', 'Chicago')]

執行結果

元組Tuple zip()函數(13/13)

# ch8_17.py
fields = ['Name', 'Age', 'Hometown']
info = ['Peter', '30', 'Chicago']
zipData = zip(fields, info)         # 執行zip
print(type(zipData))                # 列印zip資料類型
player = list(zipData)              # 將zip資料轉成串列
print(player)                       # 列印串列

f, i = zip(*player)                 # 執行unzip
print("fields = ", f)
print("info   = ", i)

zip(*元組): 將元組unzip成兩個元組

<class 'zip'>
[('Name', 'Peter'), ('Age', '30'), ('Hometown', 'Chicago')]
fields =  ('Name', 'Age', 'Hometown')
info   =  ('Peter', '30', 'Chicago')

執行結果

字典(dict)

  • 簡介

字典 簡介(1/11)

價目表 = {'香蕉': 20, '蘋果': 50, '鳳梨': 80}
print(價目表)
print(價目表['香蕉'])
# 列出字典資料型態
print("價目表資料型態是: ",type(價目表))

字典 (dict) 宣告:

字典名稱 = {鍵1: 值1, 鍵2: 值2, 鍵3: 值3..., 鍵N: 值N}
  • 字典:以{ }包含所有項目
  • 每個項目:鍵: 值,逗點分隔
  • 各個項目取值:字典名稱[鍵1],...字典名稱[鍵N]  

範例

  {'香蕉': 20, '蘋果': 50, '鳳梨': 80}

20

價目表資料型態是:  <class 'dict'>

執行結果

字典名稱[鍵N]

字典 簡介(2/11)

字典

串列

自訂名稱(鍵) A~E (其他任意名稱亦可)

自動產生索引值: 0~(N-1)

字典 = {'A':1, 'B':2, 'C':3, 'D':4, 'E':5}
score = [1, 2, 3, 4, 5]

字典 簡介(3/11)

# ch9_3.py
fruits = {'西瓜':15, '香蕉':20, '水蜜桃':25}
noodles = {'牛肉麵':100, '肉絲麵':80, '陽春麵':60}
print("水蜜桃一斤 = ", fruits['水蜜桃'], "元")
print("牛肉麵一碗 = ", noodles['牛肉麵'], "元")

範例

字典建立函式dict():

價目表 = {'香蕉': 20, '蘋果': 50, '鳳梨': 80}
成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)
print(成績單)
print(成績單['王小明'])

範例

水蜜桃一斤 =  25 元
牛肉麵一碗 =  100 元

執行結果

dict()函式中,「鍵」若為字串不能加引號

dict()

  {'王小明': 80, '李小鳳': 70, '張小華': 75}

80

執行結果

列出字典的元素?以鍵取值

字典 簡介(4/11)

列出字典的元素?以鍵取值

  • 鍵重複? 鍵可以重複(不應重複),但只能取得後者的值
  • 鍵不存在? 則會出現KeyError錯誤訊息
價目表 = {'香蕉': 20, '蘋果': 50, '香蕉': 80}
print(價目表['香蕉'])   # 80
print(價目表['鳳梨'])   # 錯誤

字典 新增與修改元素(5/11)

成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)
成績單['王小明'] = 90     # 修改
成績單['春嬌'] = 88       # 鍵不存在:新增
print(成績單)

範例

{'王小明': 90, '李小鳳': 70, '張小華': 75, '春嬌': 88}

執行結果

新增/修改元素內容

字典 (dict) 修改與新增:

# ch9_5.py
fruits = {'西瓜':15, '香蕉':20, '水蜜桃':25}
fruits['橘子'] = 18
print(fruits)
print("橘子一斤 = ", fruits['橘子'], "元")

範例

{'西瓜': 15, '香蕉': 20, '水蜜桃': 25, '橘子': 18}
橘子一斤 =  18 元

執行結果

新增內容

字典 新增與修改元素(6/11)

# ch9_7.py
fruits = {'西瓜':15, '香蕉':20, '水蜜桃':25}
print("舊價格香蕉一斤 = ", fruits['香蕉'], "元")
fruits['香蕉'] = 12
print("新價格香蕉一斤 = ", fruits['香蕉'], "元")

範例

舊價格香蕉一斤 =  20 元
新價格香蕉一斤 =  12 元

執行結果

# ch9_8.py
soldier0 = {'tag':'red', 'score':3, 'xpos':100,
            'ypos':30, 'speed':'slow' }
print("小兵的 x,y 舊座標  = ", soldier0['xpos'], ",", soldier0['ypos'] )
if soldier0['speed'] == 'slow':         # 慢
    x_move = 1
elif soldier0['speed'] == 'medium':     # 中
    x_move = 3
else:
    x_move = 5                          # 快
soldier0['xpos'] += x_move
print("小兵的 x,y 新座標  = ", soldier0['xpos'], ",", soldier0['ypos'] )

修改元素內容

字典 (dict) 修改與新增:

範例:根據'speed'鍵所對應的值,修改小兵的座標

字典 刪除元素(7/11)

成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)
del 成績單['王小明']    # 刪除王小明的成績
print(成績單)       
成績單.clear()         # 全部清除
print(成績單)

範例

{'李小鳳': 70, '張小華': 75}
{}

執行結果

.clear()全部清除

字典 (dict) 刪除

# ch9_9.py
fruits = {'西瓜':15, '香蕉':20, '水蜜桃':25}
print("舊fruits字典內容:", fruits)
del fruits['西瓜']
print("新fruits字典內容:", fruits)

舊fruits字典內容: {'西瓜': 15, '香蕉': 20, '水蜜桃': 25}
新fruits字典內容: {'香蕉': 20, '水蜜桃': 25}

執行結果

範例

字典 刪除元素(8/11)

# ch9_11.py
fruits = {'西瓜':15, '香蕉':20, '水蜜桃':25}
print("舊fruits字典內容:", fruits)
del fruits
print("新fruits字典內容:", fruits)       # 錯誤! 錯誤!

範例

舊fruits字典內容: {'西瓜': 15, '香蕉': 20, '水蜜桃': 25}
Traceback (most recent call last):
  File "/Users/leo/Python/ch9/ch9-1.py", line 5, in <module>
    print("新fruits字典內容:", fruits)       # 錯誤! 錯誤!
NameError: name 'fruits' is not defined

執行結果

刪除字典

字典 (dict) 刪除

字典 建立空字典(9/11)

# ch9_12
soldier0 = dict()           # 建立空字典
print("空小兵字典", soldier0)
soldier0['tag'] = 'red'
soldier0['score'] = 3
print("新小兵字典", soldier0)

範例

空小兵字典 {}
新小兵字典 {'tag': 'red', 'score': 3}

執行結果

刪除字典

建立空字典的方式:

空字典 = {}
空字典2 = dict()

字典 複製字典(10/11)

# ch9_13.py
fruits = {'西瓜':15, '香蕉':20, '水蜜桃':25, '蘋果':18}
cfruits = fruits.copy( )
print("位址 = ", id(fruits), "  fruits元素 = ", fruits)
print("位址 = ", id(cfruits), "  fruits元素 = ", cfruits)

範例

位址 =  4440957720   fruits元素 =  {'西瓜': 15, '香蕉': 20, '水蜜桃': 25, '蘋果': 18}
位址 =  4440957792   fruits元素 =  {'西瓜': 15, '香蕉': 20, '水蜜桃': 25, '蘋果': 18}

執行結果

複製字典.copy()

字典 len()函數(11/11)

# ch9_14.py
fruits = {'西瓜':15, '香蕉':20, '水蜜桃':25, '蘋果':18}
noodles = {'牛肉麵':100, '肉絲麵':80, '陽春麵':60}
empty_dict = {}
print("fruits字典元素數量     = ", len(fruits))
print("noodles字典元素數量    = ", len(noodles))
print("empty_dict字典元素數量 = ", len(empty_dict))

範例

fruits字典元素數量     =  4
noodles字典元素數量    =  3
empty_dict字典元素數量 =  0

執行結果

取得字典元素數量:len()函數

字典進階功能

  • 檢查:鍵是否存在
  • 取所有鍵:.keys()
  • 取所有值:.values()
  • 取所有「鍵」-「值」對:.items()
  • 取得字典內容個數: len(字典)

字典進階功能檢查鍵(1/11)

某個鍵是否存在?

  • 回傳True(存在) / False(不存在)
成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)
print('春嬌' in 成績單)      # False
print('王小明' in 成績單)    # True
請輸入鍵(key) = 水果
請輸入值(value) = 100
新的fruits字典內容 =  {'西瓜': 15, '香蕉': 20, '水蜜桃': 25, '水果': '100'}

執行結果

'鍵' in 字典

# ch9_15.py
fruits = {'西瓜':15, '香蕉':20, '水蜜桃':25}
key = input("請輸入鍵(key) = ")
value = input("請輸入值(value) = ")
if key in fruits:
    print("%s已經在字典了" % key)
else:
    fruits[key] = value
    print("新的fruits字典內容 = ", fruits)

字典進階功能檢查鍵(2/11)

範例:成績查詢與新增

  • 輸入姓名,如果已存在字典,則印出成績
  • 如果姓名不存在,則輸入成績
成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)
name = input('輸入學生姓名:')
if name in 成績單:
    print('%s的成績是: %3d' % (name,成績單.get(name)))
else:
    score = int(input('輸入成績:'))
    成績單[name] = score
    print(成績單)
輸入學生姓名:王小明
王小明的成績是:  80

執行結果

輸入學生姓名:志明
輸入成績:75
{'王小明': 80, '李小鳳': 70, '張小華': 75, '志明': 75}

字典進階功能檢查鍵(3/11)

成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)
while True:
    name = input('輸入學生姓名:(直接按Enter結束)')
    if name == '':
        print('程式結束')
        break
    if name in 成績單:
        print('%s的成績是: %3d' % (name,成績單.get(name)))
    else:
        score = int(input('輸入成績:'))
        成績單[name] = score
        print(成績單)

執行結果

輸入學生姓名:(直接按Enter結束)志明
輸入成績:80
{'王小明': 80, '李小鳳': 70, '張小華': 75, '志明': 80}
輸入學生姓名:(直接按Enter結束)春嬌
輸入成績:90
{'王小明': 80, '李小鳳': 70, '張小華': 75, '志明': 80, '春嬌': 90}
輸入學生姓名:(直接按Enter結束)志明
志明的成績是:  80
輸入學生姓名:(直接按Enter結束)
程式結束

搭配迴圈功能,可重複輸入,直到直接按Enter才結束

字典進階功能檢查鍵(4/11)

練習:新增價目表

  • 建立飲料店價目表
  • 飲料名為「鍵」,價格為「值」
  • 直接按Enter結束後,印出價目表
例如,新增三組資料後,印出價目表時應該顯示類似
{'咖啡': 100, '果汁': 80, '紅茶': 90}

字典進階功能取所有鍵(5/11)

取得所有鍵?

  • 需搭配字典.get()函式
{'王小明': 80, '李小鳳': 70, '張小華': 75}

dict_keys(['王小明', '李小鳳', '張小華'])

執行結果

字典.keys()

成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)
print(成績單)           # 鍵/值對
print(成績單.keys())    # 只取得鍵

字典無法用for迴圈直接處理

字典.keys(): 得到dict_keys型別資料

成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)
for item in 成績單.keys():
    print('%s的成績是%d' % (item, 成績單.get(item)))
王小明的成績是80
李小鳳的成績是70
張小華的成績是75

執行結果

字典進階功能取所有鍵(6/11)

範例:成績查詢與新增

  • 修改之前輸入程式,但程式結束後印出所有人成績
成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)
while True:
    name = input('輸入學生姓名:(直接按Enter結束)')
    if name == '':
        break
    if name in 成績單:
        print('%s的成績是: %3d' % (name,成績單.get(name)))
    else:
        score = int(input('輸入成績:'))
        成績單[name] = score
        print(成績單)
for item in 成績單.keys():
    print('%s的成績是%d' % (item, 成績單.get(item)))

字典進階功能取所有值(7/11)

取得所有值?

{'王小明': 80, '李小鳳': 70, '張小華': 75}
dict_values([80, 70, 75])

執行結果

字典.values()

成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)
print(成績單)             # 鍵/值對
print(成績單.values())    # 只取得值

字典.values(): 得到dict_values型別資料

成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)
values = 成績單.values()       # 所有值
avg = sum(values) / len(values)
print(avg)
75.0

執行結果

字典無法用for迴圈直接處理

字典進階功能取所有值(8/11)

範例:成績查詢與新增

  • 修改之前輸入程式,但程式結束後統計及格人數
成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)
while True:
    name = input('輸入學生姓名:(直接按Enter結束)')
    if name == '':
        break
    if name in 成績單:
        print('%s的成績是: %3d' % (name,成績單.get(name)))
    else:
        score = int(input('輸入成績:'))
        成績單[name] = score
        print(成績單)
及格人數 = 0
for score in 成績單.values():
    if score >= 60:
        及格人數 += 1
print('及格人數:%d' % 及格人數)

字典進階功能綜合練習(9/11)

練習:PM2.5 新增查詢

  • 輸入六都的PM2.5數值(台北市, 新北市, 桃園市, 台中市, 台南市, 高雄市)
    • 六都為「鍵」, PM2.5數值為「值」
  • 輸入城市名稱
    • 若城市屬於六都,則印出PM2.5值
    • 否則印出該城市不屬於六都
  • 輸入平均,則印出PM2.5平均值
  • 直接輸入Enter,程式結束

字典進階功能取所有鍵-值組合(10/11)

取得所有鍵-值組合?

  • 搭配兩個迴圈變數, 可分別對應鍵、值
{'王小明': 80, '李小鳳': 70, '張小華': 75}
dict_items([('王小明', 80), ('李小鳳', 70), ('張小華', 75)])

執行結果

字典.items()

成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)
print(成績單)             # 鍵/值對
print(成績單.items())    # 只取得值

字典.items(): 得到dict_dict型別資料

成績單 = dict(王小明=80, 李小鳳=70, 張小華=75)

for key, val in 成績單.items():
    print("%s的成績是:%3d" % (key, val))
王小明的成績是: 80
李小鳳的成績是: 70
張小華的成績是: 75

執行結果

2個迴圈變數: 1st對應「鍵], 2nd對應「值」

字典進階功能練習(11/11)

英漢字典 = dict(dog='狗', fish='魚', cat='貓', pig='豬')
print(英漢字典)
print(英漢字典.keys())
word = input('輸入英文單字?')
print(英漢字典.get(word, '找不到該單字'))
{'dog': '狗', 'fish': '魚', 'cat': '貓', 'pig': '豬'}
dict_keys(['dog', 'fish', 'cat', 'pig'])
輸入英文單字?white
找不到該單字

執行結果

練習:製作英翻中字典

  • 輸入英文單字與中文解釋,建立字典
  • 輸入英文單字,查詢對應的中文解釋

字典與串列

字典進階功能字典串列(1/6)

建立字典串列

# ch9_22.py
soldier0 = {'tag':'red', 'score':3, 'speed':'slow'}         # 建立小兵
soldier1 = {'tag':'blue', 'score':5, 'speed':'medium'}
soldier2 = {'tag':'green', 'score':10, 'speed':'fast'}
armys = [soldier0, soldier1, soldier2]                      # 小兵組成串列
for army in armys:                                          # 列印小兵
    print(army)
{'tag': 'red', 'score': 3, 'speed': 'slow'}
{'tag': 'blue', 'score': 5, 'speed': 'medium'}
{'tag': 'green', 'score': 10, 'speed': 'fast'}

執行結果

字典進階功能字典串列(2/6)

建立字典串列: 搭配range()

# ch9_23.py
armys = []                      # 建立小兵空串列
# 建立50個小兵
for soldier_number in range(50):
    soldier = {'tag':'red', 'score':3, 'speed':'slow'}
    armys.append(soldier)
# 列印前3個小兵
for soldier in armys[:3]:
    print(soldier)
# 列印小兵數量
print("小兵數量 = ", len(armys))
{'tag': 'red', 'score': 3, 'speed': 'slow'}
{'tag': 'red', 'score': 3, 'speed': 'slow'}
{'tag': 'red', 'score': 3, 'speed': 'slow'}
小兵數量 =  50

執行結果

字典進階功能字典串列(3/6)

範例:產生50個小兵,並修改第36~38小兵的設定值,最後印出前3個小兵,以及第35~40小兵的資料

# ch9_24.py
armys = []                      # 建立小兵空串列
# 建立50個小兵
for soldier_number in range(50):
    soldier = {'tag':'red', 'score':3, 'speed':'slow'}
    armys.append(soldier)
# 列印前3個小兵
print("前3名小兵資料")
for soldier in armys[:3]:
    print(soldier)
# 更改編號36到38的小兵
for soldier in armys[35:38]:
    if soldier['tag'] == 'red':
        soldier['tag'] = 'blue'
        soldier['score'] = 5
        soldier['speed'] = 'medium'
# 列印編號35到40的小兵
print("列印編號35到40小兵資料")
for soldier in armys[34:40]:
    print(soldier)

字典進階功能字典內含串列(4/6)

字典的值可以是[串列],用以記錄更複雜的對應關係,例如多個專長

# ch9_25.py
# 建立內含字串的字典
sports = {'Curry':['籃球', '美式足球'],
          'Durant':['棒球'],
          'James':['美式足球', '棒球', '籃球']}
# 列印key名字 + 字串'喜歡的運動'
for name, favorite_sport in sports.items( ):
          print("%s 喜歡的運動是: " % name)
# 列印value,這是串列
          for sport in favorite_sport:
              print("   ", sport)
sports = {'Curry':['籃球', '美式足球'],
          'Durant':['棒球'],
          'James':['美式足球', '棒球', '籃球']}

讀取時,可用.items()

for name, favorite_sport in sports.items( ):
          print(f"{name} 喜歡的運動是:")

完整範例,注意10~11行,使用內層迴圈讀取串列值

字典進階功能字典內含字典(5/6)

字典的值也可以是[字典],同樣用以記錄更複雜的對應關係

# ch9_26.py
# 建立內含字典的字典
wechat_account = {'cshung':{
                        'last_name':'洪',
                        'first_name':'錦魁',
                        'city':'台北'},
                  'kevin':{
                        'last_name':'鄭',
                        'first_name':'義盟',
                        'city':'北京'}}
# 列印內含字典的字典
for account, account_info in wechat_account.items( ):
    print("使用者帳號 = ", account)                   # 列印鍵(key)
    name = account_info['last_name'] + " " + account_info['first_name']
    print("姓名       = ", name)                      # 列印值(value)
    print("城市       = ", account_info['city'])      # 列印值(value)

字典進階功能while迴圈在字典的應用(6/6)

範例:輸入資料後,存入字典,直到輸入'n'為止

# ch9_27.py
survey_dict = {}                        # 建立市場調查空字典
market_survey = True                    # 設定迴圈布林值     

# 讀取參加市場調查者姓名和夢幻旅遊景點
while market_survey:
    name = input("\n請輸入姓名  : ")
    travel_location = input("夢幻旅遊景點: ")

# 將輸入存入survey_dict字典
    survey_dict[name] = travel_location

# 可由此決定是否離開市場調查
    repeat = input("是否還有人要參加市場調查?(y/n) ")
    if repeat != 'y':               # 不是輸入y,則離開while迴圈
        market_survey = False

# 市場調查結束
print("\n\n以下是市場調查的結果")
for user, location in survey_dict.items( ):
    print(user, "夢幻旅遊景點: ", location)

字典常用函式與方法len()函式(1/5)

len(字典): 列出字典內資料的筆數

# ch9_28.py
# 建立內含字典的字典
wechat_account = {'cshung':{
                        'last_name':'洪',
                        'first_name':'錦魁',
                        'city':'台北'},
                  'kevin':{
                        'last_name':'鄭',
                        'first_name':'義盟',
                        'city':'北京'}}
# 列印字典元素個數
print("wechat_account字典元素個數       ", len(wechat_account))
print("wechat_account['cshung']元素個數 ", len(wechat_account['cshung']))
print("wechat_account['kevin']元素個數  ", len(wechat_account['kevin']))

字典常用函式與方法fromkeys()方法(2/5)

字典.fromkeys(序列, 值): 根據「序列」與值建立字典

# ch9_29.py  將串列轉成字典
seq1 = ['name', 'city']         # 定義串列
list_dict1 = dict.fromkeys(seq1)

print("字典1 ", list_dict1)
list_dict2 = dict.fromkeys(seq1, 'Chicago')

print("字典2 ", list_dict2)
# 將元組轉成字典
seq2 = ('name', 'city')        # 定義元組
tup_dict1 = dict.fromkeys(seq2)

print("字典3 ", tup_dict1)
tup_dict2 = dict.fromkeys(seq2, 'New York')

print("字典4 ", tup_dict2)
seq1 = ['name', 'city']         # 定義串列
dict1 = dict.fromkeys(seq1)     # 建立字典, 但未給初值, 故值為None

seq2 = ['蘋果汁', '檸檬汁']         # 定義串列
dict2 = dict.fromkeys(seq2, 30)     # 建立字典, 設定初值為30

範例

字典常用函式與方法get()方法(3/5)

字典.get(鍵): 搜尋字典中[鍵]對應的值。若[鍵]不存在,回傳None

# ch9_30.py
fruits = {'Apple':20, 'Orange':25}
ret_value1 = fruits.get('Orange')
print("Value = ", ret_value1)
ret_value2 = fruits.get('Grape')
print("Value = ", ret_value2)
ret_value3 = fruits.get('Grape', 10)   # 設定預設值為10
print("Value = ", ret_value3)
fruits = {'Apple':20, 'Orange':25}
結果1 = fruits.get('Orange')      # 25
結果2 = fruits.get('Grape')       # None  

範例: 注意第7行,.get()還可設定預設值

字典常用函式與方法setdefault()方法(4/5)

字典.setdefault(鍵): 類似get()進行搜尋。

但若找不到,則將新的鍵加入字典(預設值為None)

# ch9_32.py
person = {'name':'John'}
print("原先字典內容", person)

# 'age'鍵不存在
age = person.setdefault('age')
print("增加age鍵 ", person)
print("age = ", age)

# 'sex'鍵不存在
sex = person.setdefault('sex', 'Male')
print("增加sex鍵 ", person)
print("sex = ", sex)

範例: 

字典常用函式與方法pop()方法(5/5)

字典.pop(鍵): 搜尋要刪除的[鍵]。

找到則刪除, 找不到回傳預設值或產生KeyError錯誤

# ch9_33.py
fruits = {'apple':20, 'banana':15, 'orange':22}
ret_value = fruits.pop('orange')
print("傳回刪除元素的值", ret_value)
print("刪除後的字典內容", fruits)

範例: 

# ch9_34.py
fruits = {'apple':20, 'banana':15, 'orange':22}
ret_value = fruits.pop('grape', 'does not exist')
print("傳回刪除元素的值", ret_value)
print("刪除後的字典內容", fruits)

集合

  • 簡介

集合 簡介(1/8)

s1 = {1,2,3,4,5}  # 大括弧建立集合
s2 = set()        # 空集合
print(s1)
print(s2)
print(type(s1))

集合 (set) : 儲存沒有順序、不重複的資料

集合名稱 = {元素1, 元素2, 元素3,..., 元素N}
  • 集合:以{ }包含所有項目,或以set()建立集合
  • 自動刪除重複元素
  • 每個項目:逗點分隔
  • 因沒有順序:無索引值
  • 判斷在集合裡:in, not in 運算子

建立

 {1, 2, 3, 4, 5}

set()

<class 'set'>

執行結果

串列名稱[索引值]
集合名稱[索引值]

集合 簡介(2/8)

# 由 串列 建立集合
s3 = set([6,7,8,9,10])
print(s3)
# 由元組 (Tuple) 建立集合
s4 = set((11, 12, 13, 14, 15))  
print(s4)
# 由 字典 建立集合
s5 = set({'早安': 'Good Morning', '你好': 'Hello'})
print(s5)
# 元素重複會自動刪除
s6 = set([40, 50, 60, 60, 80, 60])
print(s6)

建立

{6, 7, 8, 9, 10}
{11, 12, 13, 14, 15}
{'早安', '你好'}
{40, 50, 80, 60}

執行結果

集合其他建立方式:呼叫set()函數建立,可從串列, 元組建立

集合 簡介(3/8)

s3 = set([6,7,8,9,10])
s4 = set((11, 12, 13, 14, 15))  

s3.add(50)
print(s3)
s4.remove(15)
print(s4)

新增

{6, 7, 8, 9, 10, 50}
{11, 12, 13, 14}

執行結果

集合:新增函式 .add(), 移除函式 .remove()

移除

s4 = set((11, 12, 13, 14, 15))  

s4.remove(10)   # 錯誤!10不在集合裡
print(s4)

不能移除不在集合裡的元素

集合 簡介(4/8)

s3 = set([6,7,8,9,10])
num = 6
if num in s3:
    print(num, '在集合裡')
else:
    print(num, '不在集合裡')

存在?

6 在集合裡

執行結果

判斷元素是否在集合裡: in , not in運算子

s4 = set((11, 12, 13, 14, 15))  
print(10 not in s4)   # 10不在s4集合裡?
print(11 not in s4)   # 11不在s4集合裡?
True
False

執行結果

不存在?

集合 簡介(5/8)

s3 = set([6,7,8,9,10])

print(len(s3))
print(sum(s3))
print(max(s3))
print(min(s3))
5
40
10
6

執行結果

集合可使用的函式:

  • len(): 集合元素個數
  • sum(): 加總
  • max(): 回傳最大值
  • min(): 回傳最小值

集合 簡介(6/8)

s3 = set([6,7,8,9,10])
for item in s3:
    print(item)
6
7
8
9
10

執行結果

集合的處理方式: for迴圈

春曉 = '春眠不覺曉,處處聞啼鳥。夜來風雨聲,花落知多少?'
字集合 = set(春曉)     # 字串轉集合: 每個不重複的字成為一個元素
print(字集合)
for word in 字集合:
    print(word, end=",")
{'。', '處', '多', '少', '知', '曉', '不', '?', '春', '覺', '來', '風', '聲', '鳥', '夜', '花', '落', ',', '雨', '眠', '聞', '啼'}
。,處,多,少,知,曉,不,?,春,覺,來,風,聲,鳥,夜,花,落,,,雨,眠,聞,啼,

執行結果

集合 簡介(7/8)

集合運算子: 

a={7, 9, 8, 4, 2, 6, 5, 7, 4};
b={6, 55, 4, 12, 1 ,5}

print('a集合:', a)
print('b集合:',b)

print('a,b交集', a & b)
print('a,b聯集', a | b)
print('a,b差集', a - b)
a集合: {2, 4, 5, 6, 7, 8, 9}
b集合: {1, 4, 5, 6, 12, 55}
a,b交集 {4, 5, 6}
a,b聯集 {1, 2, 4, 5, 6, 7, 8, 9, 12, 55}
a,b差集 {8, 9, 2, 7}

執行結果

交集 &
聯集 |
差集 -

集合 簡介(8/8)

範例:找出兩科都及格與都不及格的人

# 成績:以字典儲存
數學科 = {'A001': 80, 'A002': 60, 'A003': 45, 'A004': 38, 'A005': 75} 
英文科 = {'A001': 45, 'A002': 70, 'A003': 80, 'A004': 44, 'A005': 90}

數學及格 =  set()    # 設定空集合
數學不及格 = set()
英文及格  = set()    # 設定空集合
英文不及格 = set()

for name, score in 數學科.items():  # 檢視數學科
    if score >= 60:    # 及格
        數學及格.add(name)
    else:              # 不及格
        數學不及格.add(name)
for name, score in 英文科.items():  # 檢視英文科
    if score >= 60:    # 及格
        英文及格.add(name)
    else:              # 不及格
        英文不及格.add(name)

print('兩科都及格', 數學及格 & 英文及格)
print('兩科都不及格', 數學不及格 & 英文不及格)

集合 練習

練習:找出及格的人

全班學生: John, Mary, Tina, Fiona, Claire, Eva, Ben, Bill, Bert

英文及格:John, Mary, Fiona, Claire, Ben, Bill

數學及格:Mary, Fiona, Claire, Eva, Ben

Q. 分別印出 (a) 兩科都及格 (b) 數學不及格 (c) 英文及格但數學不及格 的同學名字