SlideShare a Scribd company logo
1 of 36
Download to read offline
Python元組,字典,集合
Revised on August 26, 2021
 Python的資料結構
 元組資料與應用
 字典資料與應用
 集合資料與應用
 使用sorted()函式
 使用enumerate()函式
 應用實例 – 井字棋遊戲
 Python 支援四種資料結構:list、tuple、set及dictionary,而且彼此
問可以相互轉換
 串列類似其它程式語言的陣列 (Array),但Python 串列中的元素允許
是不同資料型別
list1 = ['apple', 23, 'orange', 15, 'melon', 19]
 元組 (tuple) 類似串列,但建立資料後,內容就不可變更
tuple1 = ('apple', 23, 'orange', 15, 'melon', 19)
 集合 (set) 為不重複的非排序元素集,可進行數學上的集合運算
set1 = {'apple', 23, 'orange', 15, 'melon', 19}
 字典 (dictionary) 用於儲存由 key 索引的鍵⋅值配對 (Key-Value Pair)
資料,鍵必須是唯⼀
dict1 = {'apple':23, 'orange':15, 'melon':19}
Python的資料結構
2
 元組 (tuple) 類似串列,元組的元素可以由不同型別的資料型別來組成,
但元組建立後元素個數及內容都不可變更
 讀取元組內的元素時,使用的註標即建立時的順序,運算速度最快
 元組的宣告
 元組變數 = 元素A, 元素B, 元素C, ...
 元組變數 = (元素A, 元素B, 元素C, ...)
tuple1 = () #宣告空元組
dummy1 = 65 #整數資料
tuple2 = 65, #宣告只有⼀個元素的元組,元素之後必須加上逗號
dummy2 = (65) #整數資料
tuple3 = (65,) #宣告只有⼀個元素的元組,元素之後必須加上逗號
tuple4 = (65, 'A') #元素可以是不同資料型別
print(tuple4[1]) #A
元組資料 1/2
 list 函式可將元組資料轉換為串列
mytuple = (1, 2, 3, 4, 5)
list1 = list(mytuple)
 tuple 函式可將串列資料轉換為元組
mylist = [1, 2, 3, 4, 5]
tuple1 = tuple(mylist)
元組資料 2/2
4
tuple1 = ('apple', 23, 'orange', 15, 'melon', 19)
tuple2 = (7, 20, 15, 40, 19.5)
 value in 元組
檢查元組中是否存在value元素值
print(50 in tuple1) #False
 元組[i]
回傳註標為i的元素值
print(tuple2[0]) #apple
 len(元組)
取得元組元素數目
print(len(tuple1)) #6
 min(元組)
取得元組中最小的元素值,只適用於元素皆為數值資料之元組
print(min(tuple2)) #7
元組的基本操作 1/2
 max(元組)
取得元組中最大的元素值,只適用於元素皆為數值資料之元組
print(max(tuple2)) #40
 sum(元組)
計算元組元素的總和,只適用於元素皆為數值資料之元組
print(sum(tuple2)) #101.5
tuple1 = ('apple', 23, 'orange', 15, 'melon', 19)
tuple1[1] = 25 #錯誤
元組的基本操作 2/2
TypeError: 'tuple' object does not support item assignment
 字典資料 (dict) 的元素由「鍵(Key):值(Value)」組成,元素間用逗號
分隔,所有元素被 {} 大括號包圍
 字典 = {鍵1:值1, 鍵2:值2, ...}
 鍵必須是唯⼀,如果鍵值重覆,前⾯鍵值的元素會被後⾯鍵值的元素覆
蓋。鍵可以使用數值、字串或元組
 值可以是任何資料型別
dict1 = {'香蕉':20, '蘋果':50, '橘子':30}
dict2 = dict(⻄瓜 = 30, 葡萄 = 45, 百香果 = 60)
print(dict1)
print(dict2)
測試結果:
{'香蕉': 20, '蘋果': 50, '橘子': 30}
{'⻄瓜': 30, '葡萄': 45, '百香果': 60}
字典資料
7
dict1 = {'香蕉':20, '蘋果':50, '橘子':30}
 字典[key] = value
在字典新增key:value元素,若已存在鍵,表示更新值
dict1['鳯梨'] = 40
 del 字典[key]
刪除字典中鍵為 key 的元素
del dict1['鳯梨']
 字典.clear()
可刪除字典的所有元素
dict1.clear()
 del 字典
刪除整個字典資料
del dict1
字典資料維護 1/2
8
dict1 = {'香蕉':20, '蘋果':50, '橘子':30}
dict1['鳯梨'] = 40
print(dict1) #{'香蕉':20, '蘋果':50, '橘子':30, '鳯梨':40}
del dict1['蘋果']
print(dict1) #{'香蕉':20, '橘子':30, '鳯梨':40}
dict1.clear()
print(dict1) #{}
del dict1
print(dict1) #錯誤
字典資料維護 2/2
NameError: name 'dict1' is not defined
dict1 = {'香蕉':20, '蘋果':50, '橘子':30}
 len(字典)
計算字典的元素個數
print(len(dict1)) #3
 字典.fromkeys(元組或串列[, 預設值])
以元組或串列元素為鍵,建立字典,如有重複元素會自動去除
fruits = ('apple', 'orange', 'melon')
fruitdic = {}.fromkeys(fruits, 30)
print(fruitdic) #{'apple': 30, 'orange': 30, 'melon': 30}
 字典.keys()
傳回字典中所有的鍵,傳回資料可用 list 函式轉換為串列
print(list(dict1.keys())) #['香蕉', '蘋果', '橘子']
 字典.values()
傳回字典中所有的值,傳回資料可用 list 函式轉換為串列
print(list(sites. values())) #[20, 50, 30]
字典資料處理 1/5
10
dict1 = {'香蕉':20, '蘋果':50, '橘子':30}
 字典.items()
傳回字典中所有的元素,每⼀對鍵值會形成⼀個元組。傳回資料可用 list 函式
轉換為串列
print(list(dict1.items())) #[('香蕉', 20), ('蘋果', 50), ('橘子', 30)]
 字典.get(key, value)
取得 key 對應的值,若 key 不存在,則傳回參數中的 value 值
print(dict1.get('鳯梨', 40)) #40
 字典.setdefault(key, value)
取得key 對應的值,若 key 不存在,則以參數的 key, value 建立新元素,並傳
回 value 值
print(dict1.setdefault('鳯梨', 40)) #40
print(dict1) #{'香蕉': 20, '蘋果': 50, '橘子': 30, '鳯梨': 40}
字典資料處理 2/5
11
dict1 = {'香蕉':20, '蘋果':50, '橘子':30}
 字典.pop(key[, value])
傳回 key 對應的值,並刪除該元素;如果找不到 key,則回傳 value;如果找
不到 key,又沒指定 value,則會造成 KeyError 異常
print(dict1.pop('蘋果')) #50
print(dict1) #{'香蕉': 20, '橘子': 30}
 字典.popitem()
傳回最後⼀筆元素 (元組資料型式),並刪除該元素;如果字典已經為空,卻調
用了此方法,就報出KeyError異常
print(dict1.pop('蘋果')) #('橘子', 30)
print(dict1) #{'香蕉': 20}
 字典.update(字典2)
以字典2的元素,更新字典
dict1.update({'香蕉':25, '蘋果':50})
print(dict1) #{'香蕉': 25, '蘋果': 50}
字典資料處理 3/5
12
dict1 = {'香蕉':20, '蘋果':50, '橘子':30}
 key in 字典
檢查字典中是否存在key鍵
print('香蕉' in dict1) #True
for key in dict1:
print(key, end = ', ') #香蕉, 蘋果, 橘子,
字典資料處理 4/5
13
sites = {'Google': 'www.google.com', 'Runoob': 'www.runoob.com'}
print(sites.get('Google'))
print(sites.popitem())
print(sites.setdefault('Python', 'www.python.org'))
print(list(sites.keys()))
print(list(sites.values()))
sites.update({'Python':'python.org'})
print(sites.items())
for k in sites:
print(k)
測試結果:
www.google.com
('Runoob', 'www.runoob.com')
www.python.org
['Google', 'Python']
['www.google.com', 'www.python.org']
dict_items([('Google', 'www.google.com'), ('Python', 'python.org')])
Google
Python
字典資料處理 5/5
 在 Python 不支援其它語言中的 switch 指令,以下程式結合字典物件
與 lambda 函式模擬 switch 指令功能
score = int(input('請輸入分數:'))
level = score // 10
{
10 : lambda: print('Perfect'),
9 : lambda: print('A'),
8 : lambda: print('B'),
7 : lambda: print('C'),
6 : lambda: print('D')
}.get(level, lambda: print('E'))()
測試結果:
請輸入分數:67
D
字典資料應用
 集合 (Set) 儲存的是無序、元素不重複的資料集
 集合名稱 = {元素1, 元素2, ...}
programmers = {'Jack', 'Sam', 'Susan', 'Janice'}
 會重新排列元素順序
 元素可以是不同資料型別
 set 函式可將串列資料轉換為集合,並自動剔除重複元素
engineers = set(['John', 'Jane', 'Jack', 'Jack', 'Janice'])
 set 函式可將字典資料中的鍵轉換為集合
s = set({1:'A', 2:'B', 3:'C', 4:'D'}) #{1,2,3,4}
 建立空集合必须用 set() 而不是使用 {} (空字典)
集合資料
16
 集合.add(x)
將元素 x 添加到集合中,如果元素已存在,則不進行任何操作
 集合.update(x)
將 x 添加到集合中,x 可以是元素、串列、元組或字典
 集合.remove(x)
將元素 x 從集合中移除,如果元素不存在,則會發生 KeyError 錯誤
 集合.discard(x)
將元素 x 從集合中移除,如果元素不存在,則不進行任何操作
 集合.pop()
取從集合中取出第⼀個元素,並移除該元素;如果是空集合,則會發生
KeyError 錯誤
 集合.clear()
清空集合
集合的基本操作 1/3
17
 len(集合)
回傳集合的元素個數
 max(集合)
回傳集合中的最大元素
 min(集合)
回傳集合中的最小元素
 x in 集合
檢查集合中是否存在元素 x
集合的基本操作 2/3
18
programmer = {'Jack', 'Sam', 'Susan', 'Janice'}
programmer.add('Tony')
print(programmer)
programmer.discard('Susan')
print('Susan' in programmer)
print(programmer)
programmer.pop()
print(programmer)
for e in programmer:
print(e)
測試結果:
{'Sam', 'Susan', 'Tony', 'Jack', 'Janice'}
False
{'Sam', 'Tony', 'Jack', 'Janice'}
{'Tony', 'Jack', 'Janice'}
Tony
Jack
Janice
集合的基本操作 3/3
 交集運算
 集合1 & 集合2
 集合1.intersection(集合2)
 聯集運算
 集合1 | 集合2
 集合1.union(集合2)
 差集運算
 集合1 – 集合2
 集合1.difference(集合2)
集合運算 1/3
20
 對稱差集 (排除相同元素)
 集合1 ^ 集合2
 集合1.symmetric_difference(集合2)
 子集合
 集合1 < 集合2 #測試s1是否為s2的子集合
 集合1.issubset(集合2)
 父集合
 集合1 > 集合2 #測試s1是否為s2的父集合
 集合1.issuperset(集合2)
 判断两集合是否包含相同的元素,如果没有回傳True,否则回傳False
 集合1.isdisjoint(集合2)
集合運算 2/3
21
engineer = set(['Tony', 'John', 'Jane', 'Jack', 'Janice'])
print(engineer)
programmer = {'Tina', 'Jack', 'Sam', 'Susan', 'Janice', 'Tom'}
manager = set(['Tony', 'Tina', 'Mike'])
employee = engineer | programmer | manager #union
print(employee)
print('engineer and manager:', engineer & manager) #intersection
print('fulltime manager:', manager - engineer - programmer) #difference
engineer.remove('Jane')
print(engineer)
print(len(engineer))
測試結果:
{'John', 'Jane', 'Tony', 'Jack', 'Janice'}
{'Tom', 'Sam', 'John', 'Jane', 'Tony', 'Susan', 'Mike', 'Jack', 'Tina',
'Janice'}
engineer and manager: {'Tony'}
fulltime manager: {'Mike'}
{'John', 'Tony', 'Jack', 'Janice'}
4
集合運算 3/3
 只有字典提供鍵值索引,而串列、元組及集合這三者極為相似;串列
因為限制少,方便使用但效率會低於其他型別
 依資料的性質
 如果資料有兩個以上,且包含唯⼀的關鍵字,那麼字典是絕佳的選擇
 如果資料有前後順序的時間因素,或者有可能會重複時,就不能使用集合
 資料如果有增減的需求,元組就無法達成要求
 考量資料內建的函式和方法,是否能對資料進行處理
 集合型別可以有效率的進行聯集、交集等運算
元組、字典和集合使用時機
 sorted() 函式可用來排序任何的 iterable 資料 (string, dictionary,
tuple...),並串列型別回傳排序後之資料
 sorted(iterable, key = None, reverse = False)
 iterable
可迭代運算物件
 key
key 參數的值應該是⼀個函數,它接受⼀個參數並返回⼀個用於排序目的
的鍵。只有當可迭代運算物件的元素為複合資料時,才需
 reverse
排序規則,reverse = True 降冪,reverse = False 昇冪 (預設)
sorted ()函式 1/4
programmers = {'Jack', 'Sam', 'Allen', 'David'}
print(sorted(programmers))
print(sorted(programmers, reverse = True))
fruits = {'apple':23, 'orange':15, 'melon':19}
print(sorted(fruits)) #字典資料預設以key排序
print(sorted(fruits, key = lambda x:fruits[x])) #使用value排序字典資料
測試結果:
['Allen', 'David', 'Jack', 'Sam']
['Sam', 'Jack', 'David', 'Allen']
['apple', 'melon', 'orange']
['orange', 'melon', 'apple']
sorted ()函式 2/4
 由於經常會用到 key 函式,Python 提供 operator 模組,其中
itemgetter() 函式可以直接做為 key 函式
fruits = {'apple':23, 'orange':15, 'melon':19}
print(sorted(fruits, key = itemgetter(0))) #使用key排序字典資料
print(sorted(fruits, key = itemgetter(1))) #使用value排序字典資料
students = [('Bill', 'B', 15), ('Danny', 'A', 14), ('Geoff', 'B', 14)]
print(sorted(students))
print(sorted(students, key = lambda x:x[1])) #以成績排序資料
print(sorted(students, key = itemgetter(1))) #以成績排序資料
print(sorted(students, key = lambda x:(x[1], x[2]))) #先以成績再以年齡排序資料
print(sorted(students, key = itemgetter(1, 2))) #先以成績再以年齡排序資料
測試結果:
['apple', 'melon', 'orange']
['melon', 'apple', 'orange']
[('Bill', 'B', 15), ('Danny', 'A', 14), ('Geoff', 'B', 14)]
[('Danny', 'A', 14), ('Bill', 'B', 15), ('Geoff', 'B', 14)]
[('Danny', 'A', 14), ('Bill', 'B', 15), ('Geoff', 'B', 14)]
[('Danny', 'A', 14), ('Geoff', 'B', 14), ('Bill', 'B', 15)]
[('Danny', 'A', 14), ('Geoff', 'B', 14), ('Bill', 'B', 15)]
sorted ()函式 3/4
 如果要排序的物件是class object的話,也可以使用operator模組中的
attrgetter() 做為 key 函式
class Student:
def __init__(self, name, grade, age):
self.name = name
self.grade = grade
self.age = age
def __repr__(self):
return repr((self.name, self.grade, self.age))
students = [Student('Bill', 'B', 15), Student('Danny', 'A', 14),
Student('Geoff', 'B', 14)]
print(sorted(students, key = attrgetter('grade'))) #比成績
print(sorted(students, key = attrgetter('grade', 'age'))) #先比成績再比年齡
測試結果:
[('Danny', 'A', 14), ('Bill', 'B', 15), ('Geoff', 'B', 14)]
[('Danny', 'A', 14), ('Geoff', 'B', 14), ('Bill', 'B', 15)]
註:有關類別宣告後續單元再介紹
sorted ()函式 4/4
 enumerate() 函式用來自可叠代對象 (如串列、元組、集合等) 中依序
列舉出元素值,並加以順序編號
 enumerate(sequence, [start = 0])
 start 為將列舉所取得資料進行編號之起始值,預設值為 0
 enumerate 多用於在 for 循環中得到計數,利用它可以同時獲得索引
和值,即需要 index 和 value 值的時候可以使用
programmer = {'Jack', 'Sam', 'Susan', 'Janice'}
for index, name in enumerate(programmer, start = 1):
print('%s. %s' %(index, name))
測試結果:
1. Susan
2. Sam
3. Janice
4. Jack
enumerate()函式
 遊戲規則
 由玩家 (X) 與電腦 (O) 輪流對奕,隨機決定先手
 先連成⼀線者勝出
 電腦落子策略
1. 檢查棋盤,如有決勝點即落子
2. 檢查棋盤,如存在對手決勝點,落子阻斷
3. 依據棋盤空格優先序落子
1) 四個角落空格
2) 中間空格
3) 四個邊空格
應用實例:井字棋遊戲 1/8
 建立board串列儲存對奕資料,元素 1 ~元素 9 對應井字棋盤九格,元
素 0 沒使用;'X'表示玩家落子,'O'表示電腦落子,' '表示空格
import random
board = [' ' for x in range(10)]
 printBoard() 自訂函式用來顯示井字棋
def printBoard():
print(' ' + board[1] + '|' + board[2] + '|' + board[3] + ' ')
print('--+-+--')
print(' ' + board[4] + '|' + board[5] + '|' + board[6] + ' ')
print('--+-+--')
print(' ' + board[7] + '|' + board[8] + '|' + board[9] + ' ')
應用實例:井字棋遊戲 2/8
1 2 3
4 5 6
7 8 9
 isWinner(bo, c)自訂函式用來檢查是否連線,有連線時回傳 True
 bo 井字棋對奕資料
 c 為棋子符號,'X'代表玩家,'O'代表電腦
def isWinner(bo, c):
return (bo[1]==bo[2]==bo[3]==c) or (bo[4]==bo[5]==bo[6]==c) or 
(bo[7]==bo[8]==bo[9]==c) or (bo[1]==bo[4]==bo[7]==c) or 
(bo[2]==bo[5]==bo[8]==c) or (bo[3]==bo[6]==bo[9]==c) or 
(bo[1]==bo[5]==bo[9]==c) or (bo[3]==bo[5]==bo[7]==c)
 isBoardFull(bo)自訂函式用來檢查井字棋是否填滿了
def isBoardFull():
return board.count(' ') == 1 #只剩⼀個空格時(元素0),表示棋盤已填滿
 selectRandom(li)自訂函式用來自li串列中隨機挑選⼀個元素值
def selectRandom(li):
r = random.randrange(0, len(li))
return li[r]
應用實例:井字棋遊戲 3/8
 playerTurn()自訂函式為玩家回合處理作業,若玩家輸入的棋盤位
置編號為空格則落子'X',否則重新輸入
def playerTurn():
while True:
try:
move = int(input('Select a position to place an 'X' (1-9): '))
if move > 0 and move < 10:
if (board[move] == ' '):
board[move] = 'X'
break
else:
print('Sorry, this space is occupied!')
else:
print('Please type a number within the range!')
except:
print('Please type a number!')
printBoard() #顯示棋盤目前結果
應用實例:井字棋遊戲 4/8
1 2 3
4 5 6
7 8 9
 evaluateMove()自訂函式為電腦回合計算最佳落子位置
 落子優先序:連線決勝點、阻斷對手連線點、四個角落、中間、四個邊
def evaluateMove():
candiate = tuple([x for x, c in enumerate(board) if c == ' ' and x != 0])
for let in ('O', 'X'): #檢查決勝點及阻斷對手決勝點
for i in candiate :
boardCopy = board[:] #複製棋盤以便測試
boardCopy[i] = let
if isWinner(boardCopy, let):
return i
cornersOpen = []
for i in candiate :
if i in (1, 3, 7, 9):
cornersOpen.append(i)
if len(cornersOpen) > 0: #選擇四個角落位置
return selectRandom(cornersOpen)
應用實例:井字棋遊戲 5/8
if 5 in candiate: #選擇中間位置
return 5
edgesOpen = []
for i in candiate:
if i in (2, 4, 6, 8):
edgesOpen.append(i)
if len(edgesOpen) > 0: #選擇四邊位置
return selectRandom(edgesOpen)
 computerTurn()自訂函式為電腦回合處理作業
def computerTurn():
move = evaluateMove()
board[move] = 'O'
print('Computer placed an 'O' in position', move)
printBoard() #顯示棋盤目前結果
應用實例:井字棋遊戲 6/8
 game()自訂函式為遊戲流程控制作業
def game(turn):
while True:
if (turn):
playerTurn() #玩家回合
turn = 1 - turn #換手
if isWinner(board, 'X'):
print('You won this time!')
break;
else:
computerTurn() #電腦回合
turn = 1 - turn #換手
if isWinner(board, 'O'):
print('Computer won this time!')
break;
if isBoardFull():
print('Tie Game!')
break;
應用實例:井字棋遊戲 7/8
 程式主流程
while True:
print('Welcome to Tic Tac Toe!', end = ', ')
turn = random.randint(0, 9) % 2 #隨機決定先手,0電腦, 1玩家
if (turn == 1):
print('玩家先下')
printBoard() #畫出空棋盤
else:
print('電腦先下')
game(turn)
answer = input('Do you want to play again? (Y/N)')
if answer.lower() == 'y' or answer.lower == 'yes':
board = [' ' for x in range(10)]
print('-----------------------------------')
else:
break
應用實例:井字棋遊戲 8/8

More Related Content

What's hot (20)

Appendix B 範例
Appendix B 範例Appendix B 範例
Appendix B 範例
 
C程式-函式與巨集
C程式-函式與巨集C程式-函式與巨集
C程式-函式與巨集
 
C語言陣列與字串
C語言陣列與字串C語言陣列與字串
C語言陣列與字串
 
C程式-陣列與指標
C程式-陣列與指標C程式-陣列與指標
C程式-陣列與指標
 
Ch10 教學
Ch10 教學Ch10 教學
Ch10 教學
 
C語言標準輸出入函式
C語言標準輸出入函式C語言標準輸出入函式
C語言標準輸出入函式
 
第5章数组
第5章数组第5章数组
第5章数组
 
Ch10 範例
Ch10 範例Ch10 範例
Ch10 範例
 
Sql培训 (1)
Sql培训 (1)Sql培训 (1)
Sql培训 (1)
 
Python程式設計 - 分支作業
Python程式設計 - 分支作業Python程式設計 - 分支作業
Python程式設計 - 分支作業
 
C語言結構與串列
C語言結構與串列 C語言結構與串列
C語言結構與串列
 
建置Python開發環境
建置Python開發環境建置Python開發環境
建置Python開發環境
 
Ch9 教學
Ch9 教學Ch9 教學
Ch9 教學
 
Ch7 教學
Ch7 教學Ch7 教學
Ch7 教學
 
Python入門:5大概念初心者必備 2021/11/18
Python入門:5大概念初心者必備 2021/11/18Python入門:5大概念初心者必備 2021/11/18
Python入門:5大概念初心者必備 2021/11/18
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集
 
Python入門:5大概念初心者必備
Python入門:5大概念初心者必備Python入門:5大概念初心者必備
Python入門:5大概念初心者必備
 
Ch8 教學
Ch8 教學Ch8 教學
Ch8 教學
 
Ch9
Ch9Ch9
Ch9
 
Python learn guide
Python learn guidePython learn guide
Python learn guide
 

Similar to Python元組,字典,集合

第01章 绪论(java版)
第01章  绪论(java版)第01章  绪论(java版)
第01章 绪论(java版)Yan Li
 
Arrays的Sort算法分析
Arrays的Sort算法分析Arrays的Sort算法分析
Arrays的Sort算法分析Zianed Hou
 
系統程式 -- 第 12 章 系統軟體實作
系統程式 -- 第 12 章 系統軟體實作系統程式 -- 第 12 章 系統軟體實作
系統程式 -- 第 12 章 系統軟體實作鍾誠 陳鍾誠
 
手把手打開Python資料分析大門
手把手打開Python資料分析大門手把手打開Python資料分析大門
手把手打開Python資料分析大門Yen-lung Tsai
 
Python学习笔记
Python学习笔记Python学习笔记
Python学习笔记Lingfei Kong
 
Js is js(程劭非) (1)
Js is js(程劭非) (1)Js is js(程劭非) (1)
Js is js(程劭非) (1)looneyren
 
Scilab introduction(Scilab 介紹)
Scilab introduction(Scilab 介紹)Scilab introduction(Scilab 介紹)
Scilab introduction(Scilab 介紹)JIANG MING-LI
 
20161209-Julia Taiwan first meetup-julia語言入門
20161209-Julia Taiwan first meetup-julia語言入門20161209-Julia Taiwan first meetup-julia語言入門
20161209-Julia Taiwan first meetup-julia語言入門岳華 杜
 
ncuma_串列.pptx
ncuma_串列.pptxncuma_串列.pptx
ncuma_串列.pptxNCU MCL
 
实验一 Mathematica软件简介
实验一   Mathematica软件简介实验一   Mathematica软件简介
实验一 Mathematica软件简介guestfe33f0e
 
实验一 Mathematica软件简介
实验一   Mathematica软件简介实验一   Mathematica软件简介
实验一 Mathematica软件简介Xin Zheng
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀Shengyou Fan
 

Similar to Python元組,字典,集合 (20)

Ch8
Ch8Ch8
Ch8
 
第01章 绪论(java版)
第01章  绪论(java版)第01章  绪论(java版)
第01章 绪论(java版)
 
Scala+RDD
Scala+RDDScala+RDD
Scala+RDD
 
Arrays的Sort算法分析
Arrays的Sort算法分析Arrays的Sort算法分析
Arrays的Sort算法分析
 
Ch12
Ch12Ch12
Ch12
 
Ch5
Ch5Ch5
Ch5
 
Ch11
Ch11Ch11
Ch11
 
Ch11 教學
Ch11 教學Ch11 教學
Ch11 教學
 
系統程式 -- 第 12 章 系統軟體實作
系統程式 -- 第 12 章 系統軟體實作系統程式 -- 第 12 章 系統軟體實作
系統程式 -- 第 12 章 系統軟體實作
 
手把手打開Python資料分析大門
手把手打開Python資料分析大門手把手打開Python資料分析大門
手把手打開Python資料分析大門
 
Scala+spark 2nd
Scala+spark 2ndScala+spark 2nd
Scala+spark 2nd
 
Python学习笔记
Python学习笔记Python学习笔记
Python学习笔记
 
Js is js(程劭非) (1)
Js is js(程劭非) (1)Js is js(程劭非) (1)
Js is js(程劭非) (1)
 
Ch7
Ch7Ch7
Ch7
 
Scilab introduction(Scilab 介紹)
Scilab introduction(Scilab 介紹)Scilab introduction(Scilab 介紹)
Scilab introduction(Scilab 介紹)
 
20161209-Julia Taiwan first meetup-julia語言入門
20161209-Julia Taiwan first meetup-julia語言入門20161209-Julia Taiwan first meetup-julia語言入門
20161209-Julia Taiwan first meetup-julia語言入門
 
ncuma_串列.pptx
ncuma_串列.pptxncuma_串列.pptx
ncuma_串列.pptx
 
实验一 Mathematica软件简介
实验一   Mathematica软件简介实验一   Mathematica软件简介
实验一 Mathematica软件简介
 
实验一 Mathematica软件简介
实验一   Mathematica软件简介实验一   Mathematica软件简介
实验一 Mathematica软件简介
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
 

More from 吳錫修 (ShyiShiou Wu)

mbot2.0教學-陀螺儀與三軸加速計應用.pdf
mbot2.0教學-陀螺儀與三軸加速計應用.pdfmbot2.0教學-陀螺儀與三軸加速計應用.pdf
mbot2.0教學-陀螺儀與三軸加速計應用.pdf吳錫修 (ShyiShiou Wu)
 
mbot2.0教學-四路顏色感測器應用.pdf
mbot2.0教學-四路顏色感測器應用.pdfmbot2.0教學-四路顏色感測器應用.pdf
mbot2.0教學-四路顏色感測器應用.pdf吳錫修 (ShyiShiou Wu)
 
mbot2.0教學-mblock5開發mBot 2.0應用程式.pdf
mbot2.0教學-mblock5開發mBot 2.0應用程式.pdfmbot2.0教學-mblock5開發mBot 2.0應用程式.pdf
mbot2.0教學-mblock5開發mBot 2.0應用程式.pdf吳錫修 (ShyiShiou Wu)
 

More from 吳錫修 (ShyiShiou Wu) (20)

mbot2.0教學-陀螺儀與三軸加速計應用.pdf
mbot2.0教學-陀螺儀與三軸加速計應用.pdfmbot2.0教學-陀螺儀與三軸加速計應用.pdf
mbot2.0教學-陀螺儀與三軸加速計應用.pdf
 
mbot2.0教學-使用makeblock雲服務.pdf
mbot2.0教學-使用makeblock雲服務.pdfmbot2.0教學-使用makeblock雲服務.pdf
mbot2.0教學-使用makeblock雲服務.pdf
 
mbot2.0教學-局域網路傳輸應用.pdf
mbot2.0教學-局域網路傳輸應用.pdfmbot2.0教學-局域網路傳輸應用.pdf
mbot2.0教學-局域網路傳輸應用.pdf
 
mbot2.0教學-四路顏色感測器應用.pdf
mbot2.0教學-四路顏色感測器應用.pdfmbot2.0教學-四路顏色感測器應用.pdf
mbot2.0教學-四路顏色感測器應用.pdf
 
mbot2.0教學-聲光控制應用.pdf
mbot2.0教學-聲光控制應用.pdfmbot2.0教學-聲光控制應用.pdf
mbot2.0教學-聲光控制應用.pdf
 
mbot2.0教學-光感測器與LED應用.pdf
mbot2.0教學-光感測器與LED應用.pdfmbot2.0教學-光感測器與LED應用.pdf
mbot2.0教學-光感測器與LED應用.pdf
 
mbot2.0教學-超音波感測應用.pdf
mbot2.0教學-超音波感測應用.pdfmbot2.0教學-超音波感測應用.pdf
mbot2.0教學-超音波感測應用.pdf
 
mbot2.0教學-移動控制.pdf
mbot2.0教學-移動控制.pdfmbot2.0教學-移動控制.pdf
mbot2.0教學-移動控制.pdf
 
mbot2.0教學-mblock5開發mBot 2.0應用程式.pdf
mbot2.0教學-mblock5開發mBot 2.0應用程式.pdfmbot2.0教學-mblock5開發mBot 2.0應用程式.pdf
mbot2.0教學-mblock5開發mBot 2.0應用程式.pdf
 
mbot2.0教學-組裝與測試.pdf
mbot2.0教學-組裝與測試.pdfmbot2.0教學-組裝與測試.pdf
mbot2.0教學-組裝與測試.pdf
 
Python函式
Python函式Python函式
Python函式
 
micro:bit加速度感測應用
micro:bit加速度感測應用micro:bit加速度感測應用
micro:bit加速度感測應用
 
C語言檔案處理
C語言檔案處理C語言檔案處理
C語言檔案處理
 
C語言列舉與聯合
C語言列舉與聯合C語言列舉與聯合
C語言列舉與聯合
 
C語言函式
C語言函式C語言函式
C語言函式
 
C語言迴圈作業
C語言迴圈作業C語言迴圈作業
C語言迴圈作業
 
C語言分支流程
C語言分支流程C語言分支流程
C語言分支流程
 
C語言運算式和運算子
C語言運算式和運算子C語言運算式和運算子
C語言運算式和運算子
 
C語言基本資料型別與變數
C語言基本資料型別與變數C語言基本資料型別與變數
C語言基本資料型別與變數
 
C語言初體驗
C語言初體驗C語言初體驗
C語言初體驗
 

Python元組,字典,集合

  • 1. Python元組,字典,集合 Revised on August 26, 2021  Python的資料結構  元組資料與應用  字典資料與應用  集合資料與應用  使用sorted()函式  使用enumerate()函式  應用實例 – 井字棋遊戲
  • 2.  Python 支援四種資料結構:list、tuple、set及dictionary,而且彼此 問可以相互轉換  串列類似其它程式語言的陣列 (Array),但Python 串列中的元素允許 是不同資料型別 list1 = ['apple', 23, 'orange', 15, 'melon', 19]  元組 (tuple) 類似串列,但建立資料後,內容就不可變更 tuple1 = ('apple', 23, 'orange', 15, 'melon', 19)  集合 (set) 為不重複的非排序元素集,可進行數學上的集合運算 set1 = {'apple', 23, 'orange', 15, 'melon', 19}  字典 (dictionary) 用於儲存由 key 索引的鍵⋅值配對 (Key-Value Pair) 資料,鍵必須是唯⼀ dict1 = {'apple':23, 'orange':15, 'melon':19} Python的資料結構 2
  • 3.  元組 (tuple) 類似串列,元組的元素可以由不同型別的資料型別來組成, 但元組建立後元素個數及內容都不可變更  讀取元組內的元素時,使用的註標即建立時的順序,運算速度最快  元組的宣告  元組變數 = 元素A, 元素B, 元素C, ...  元組變數 = (元素A, 元素B, 元素C, ...) tuple1 = () #宣告空元組 dummy1 = 65 #整數資料 tuple2 = 65, #宣告只有⼀個元素的元組,元素之後必須加上逗號 dummy2 = (65) #整數資料 tuple3 = (65,) #宣告只有⼀個元素的元組,元素之後必須加上逗號 tuple4 = (65, 'A') #元素可以是不同資料型別 print(tuple4[1]) #A 元組資料 1/2
  • 4.  list 函式可將元組資料轉換為串列 mytuple = (1, 2, 3, 4, 5) list1 = list(mytuple)  tuple 函式可將串列資料轉換為元組 mylist = [1, 2, 3, 4, 5] tuple1 = tuple(mylist) 元組資料 2/2 4
  • 5. tuple1 = ('apple', 23, 'orange', 15, 'melon', 19) tuple2 = (7, 20, 15, 40, 19.5)  value in 元組 檢查元組中是否存在value元素值 print(50 in tuple1) #False  元組[i] 回傳註標為i的元素值 print(tuple2[0]) #apple  len(元組) 取得元組元素數目 print(len(tuple1)) #6  min(元組) 取得元組中最小的元素值,只適用於元素皆為數值資料之元組 print(min(tuple2)) #7 元組的基本操作 1/2
  • 6.  max(元組) 取得元組中最大的元素值,只適用於元素皆為數值資料之元組 print(max(tuple2)) #40  sum(元組) 計算元組元素的總和,只適用於元素皆為數值資料之元組 print(sum(tuple2)) #101.5 tuple1 = ('apple', 23, 'orange', 15, 'melon', 19) tuple1[1] = 25 #錯誤 元組的基本操作 2/2 TypeError: 'tuple' object does not support item assignment
  • 7.  字典資料 (dict) 的元素由「鍵(Key):值(Value)」組成,元素間用逗號 分隔,所有元素被 {} 大括號包圍  字典 = {鍵1:值1, 鍵2:值2, ...}  鍵必須是唯⼀,如果鍵值重覆,前⾯鍵值的元素會被後⾯鍵值的元素覆 蓋。鍵可以使用數值、字串或元組  值可以是任何資料型別 dict1 = {'香蕉':20, '蘋果':50, '橘子':30} dict2 = dict(⻄瓜 = 30, 葡萄 = 45, 百香果 = 60) print(dict1) print(dict2) 測試結果: {'香蕉': 20, '蘋果': 50, '橘子': 30} {'⻄瓜': 30, '葡萄': 45, '百香果': 60} 字典資料 7
  • 8. dict1 = {'香蕉':20, '蘋果':50, '橘子':30}  字典[key] = value 在字典新增key:value元素,若已存在鍵,表示更新值 dict1['鳯梨'] = 40  del 字典[key] 刪除字典中鍵為 key 的元素 del dict1['鳯梨']  字典.clear() 可刪除字典的所有元素 dict1.clear()  del 字典 刪除整個字典資料 del dict1 字典資料維護 1/2 8
  • 9. dict1 = {'香蕉':20, '蘋果':50, '橘子':30} dict1['鳯梨'] = 40 print(dict1) #{'香蕉':20, '蘋果':50, '橘子':30, '鳯梨':40} del dict1['蘋果'] print(dict1) #{'香蕉':20, '橘子':30, '鳯梨':40} dict1.clear() print(dict1) #{} del dict1 print(dict1) #錯誤 字典資料維護 2/2 NameError: name 'dict1' is not defined
  • 10. dict1 = {'香蕉':20, '蘋果':50, '橘子':30}  len(字典) 計算字典的元素個數 print(len(dict1)) #3  字典.fromkeys(元組或串列[, 預設值]) 以元組或串列元素為鍵,建立字典,如有重複元素會自動去除 fruits = ('apple', 'orange', 'melon') fruitdic = {}.fromkeys(fruits, 30) print(fruitdic) #{'apple': 30, 'orange': 30, 'melon': 30}  字典.keys() 傳回字典中所有的鍵,傳回資料可用 list 函式轉換為串列 print(list(dict1.keys())) #['香蕉', '蘋果', '橘子']  字典.values() 傳回字典中所有的值,傳回資料可用 list 函式轉換為串列 print(list(sites. values())) #[20, 50, 30] 字典資料處理 1/5 10
  • 11. dict1 = {'香蕉':20, '蘋果':50, '橘子':30}  字典.items() 傳回字典中所有的元素,每⼀對鍵值會形成⼀個元組。傳回資料可用 list 函式 轉換為串列 print(list(dict1.items())) #[('香蕉', 20), ('蘋果', 50), ('橘子', 30)]  字典.get(key, value) 取得 key 對應的值,若 key 不存在,則傳回參數中的 value 值 print(dict1.get('鳯梨', 40)) #40  字典.setdefault(key, value) 取得key 對應的值,若 key 不存在,則以參數的 key, value 建立新元素,並傳 回 value 值 print(dict1.setdefault('鳯梨', 40)) #40 print(dict1) #{'香蕉': 20, '蘋果': 50, '橘子': 30, '鳯梨': 40} 字典資料處理 2/5 11
  • 12. dict1 = {'香蕉':20, '蘋果':50, '橘子':30}  字典.pop(key[, value]) 傳回 key 對應的值,並刪除該元素;如果找不到 key,則回傳 value;如果找 不到 key,又沒指定 value,則會造成 KeyError 異常 print(dict1.pop('蘋果')) #50 print(dict1) #{'香蕉': 20, '橘子': 30}  字典.popitem() 傳回最後⼀筆元素 (元組資料型式),並刪除該元素;如果字典已經為空,卻調 用了此方法,就報出KeyError異常 print(dict1.pop('蘋果')) #('橘子', 30) print(dict1) #{'香蕉': 20}  字典.update(字典2) 以字典2的元素,更新字典 dict1.update({'香蕉':25, '蘋果':50}) print(dict1) #{'香蕉': 25, '蘋果': 50} 字典資料處理 3/5 12
  • 13. dict1 = {'香蕉':20, '蘋果':50, '橘子':30}  key in 字典 檢查字典中是否存在key鍵 print('香蕉' in dict1) #True for key in dict1: print(key, end = ', ') #香蕉, 蘋果, 橘子, 字典資料處理 4/5 13
  • 14. sites = {'Google': 'www.google.com', 'Runoob': 'www.runoob.com'} print(sites.get('Google')) print(sites.popitem()) print(sites.setdefault('Python', 'www.python.org')) print(list(sites.keys())) print(list(sites.values())) sites.update({'Python':'python.org'}) print(sites.items()) for k in sites: print(k) 測試結果: www.google.com ('Runoob', 'www.runoob.com') www.python.org ['Google', 'Python'] ['www.google.com', 'www.python.org'] dict_items([('Google', 'www.google.com'), ('Python', 'python.org')]) Google Python 字典資料處理 5/5
  • 15.  在 Python 不支援其它語言中的 switch 指令,以下程式結合字典物件 與 lambda 函式模擬 switch 指令功能 score = int(input('請輸入分數:')) level = score // 10 { 10 : lambda: print('Perfect'), 9 : lambda: print('A'), 8 : lambda: print('B'), 7 : lambda: print('C'), 6 : lambda: print('D') }.get(level, lambda: print('E'))() 測試結果: 請輸入分數:67 D 字典資料應用
  • 16.  集合 (Set) 儲存的是無序、元素不重複的資料集  集合名稱 = {元素1, 元素2, ...} programmers = {'Jack', 'Sam', 'Susan', 'Janice'}  會重新排列元素順序  元素可以是不同資料型別  set 函式可將串列資料轉換為集合,並自動剔除重複元素 engineers = set(['John', 'Jane', 'Jack', 'Jack', 'Janice'])  set 函式可將字典資料中的鍵轉換為集合 s = set({1:'A', 2:'B', 3:'C', 4:'D'}) #{1,2,3,4}  建立空集合必须用 set() 而不是使用 {} (空字典) 集合資料 16
  • 17.  集合.add(x) 將元素 x 添加到集合中,如果元素已存在,則不進行任何操作  集合.update(x) 將 x 添加到集合中,x 可以是元素、串列、元組或字典  集合.remove(x) 將元素 x 從集合中移除,如果元素不存在,則會發生 KeyError 錯誤  集合.discard(x) 將元素 x 從集合中移除,如果元素不存在,則不進行任何操作  集合.pop() 取從集合中取出第⼀個元素,並移除該元素;如果是空集合,則會發生 KeyError 錯誤  集合.clear() 清空集合 集合的基本操作 1/3 17
  • 18.  len(集合) 回傳集合的元素個數  max(集合) 回傳集合中的最大元素  min(集合) 回傳集合中的最小元素  x in 集合 檢查集合中是否存在元素 x 集合的基本操作 2/3 18
  • 19. programmer = {'Jack', 'Sam', 'Susan', 'Janice'} programmer.add('Tony') print(programmer) programmer.discard('Susan') print('Susan' in programmer) print(programmer) programmer.pop() print(programmer) for e in programmer: print(e) 測試結果: {'Sam', 'Susan', 'Tony', 'Jack', 'Janice'} False {'Sam', 'Tony', 'Jack', 'Janice'} {'Tony', 'Jack', 'Janice'} Tony Jack Janice 集合的基本操作 3/3
  • 20.  交集運算  集合1 & 集合2  集合1.intersection(集合2)  聯集運算  集合1 | 集合2  集合1.union(集合2)  差集運算  集合1 – 集合2  集合1.difference(集合2) 集合運算 1/3 20
  • 21.  對稱差集 (排除相同元素)  集合1 ^ 集合2  集合1.symmetric_difference(集合2)  子集合  集合1 < 集合2 #測試s1是否為s2的子集合  集合1.issubset(集合2)  父集合  集合1 > 集合2 #測試s1是否為s2的父集合  集合1.issuperset(集合2)  判断两集合是否包含相同的元素,如果没有回傳True,否则回傳False  集合1.isdisjoint(集合2) 集合運算 2/3 21
  • 22. engineer = set(['Tony', 'John', 'Jane', 'Jack', 'Janice']) print(engineer) programmer = {'Tina', 'Jack', 'Sam', 'Susan', 'Janice', 'Tom'} manager = set(['Tony', 'Tina', 'Mike']) employee = engineer | programmer | manager #union print(employee) print('engineer and manager:', engineer & manager) #intersection print('fulltime manager:', manager - engineer - programmer) #difference engineer.remove('Jane') print(engineer) print(len(engineer)) 測試結果: {'John', 'Jane', 'Tony', 'Jack', 'Janice'} {'Tom', 'Sam', 'John', 'Jane', 'Tony', 'Susan', 'Mike', 'Jack', 'Tina', 'Janice'} engineer and manager: {'Tony'} fulltime manager: {'Mike'} {'John', 'Tony', 'Jack', 'Janice'} 4 集合運算 3/3
  • 23.  只有字典提供鍵值索引,而串列、元組及集合這三者極為相似;串列 因為限制少,方便使用但效率會低於其他型別  依資料的性質  如果資料有兩個以上,且包含唯⼀的關鍵字,那麼字典是絕佳的選擇  如果資料有前後順序的時間因素,或者有可能會重複時,就不能使用集合  資料如果有增減的需求,元組就無法達成要求  考量資料內建的函式和方法,是否能對資料進行處理  集合型別可以有效率的進行聯集、交集等運算 元組、字典和集合使用時機
  • 24.  sorted() 函式可用來排序任何的 iterable 資料 (string, dictionary, tuple...),並串列型別回傳排序後之資料  sorted(iterable, key = None, reverse = False)  iterable 可迭代運算物件  key key 參數的值應該是⼀個函數,它接受⼀個參數並返回⼀個用於排序目的 的鍵。只有當可迭代運算物件的元素為複合資料時,才需  reverse 排序規則,reverse = True 降冪,reverse = False 昇冪 (預設) sorted ()函式 1/4
  • 25. programmers = {'Jack', 'Sam', 'Allen', 'David'} print(sorted(programmers)) print(sorted(programmers, reverse = True)) fruits = {'apple':23, 'orange':15, 'melon':19} print(sorted(fruits)) #字典資料預設以key排序 print(sorted(fruits, key = lambda x:fruits[x])) #使用value排序字典資料 測試結果: ['Allen', 'David', 'Jack', 'Sam'] ['Sam', 'Jack', 'David', 'Allen'] ['apple', 'melon', 'orange'] ['orange', 'melon', 'apple'] sorted ()函式 2/4
  • 26.  由於經常會用到 key 函式,Python 提供 operator 模組,其中 itemgetter() 函式可以直接做為 key 函式 fruits = {'apple':23, 'orange':15, 'melon':19} print(sorted(fruits, key = itemgetter(0))) #使用key排序字典資料 print(sorted(fruits, key = itemgetter(1))) #使用value排序字典資料 students = [('Bill', 'B', 15), ('Danny', 'A', 14), ('Geoff', 'B', 14)] print(sorted(students)) print(sorted(students, key = lambda x:x[1])) #以成績排序資料 print(sorted(students, key = itemgetter(1))) #以成績排序資料 print(sorted(students, key = lambda x:(x[1], x[2]))) #先以成績再以年齡排序資料 print(sorted(students, key = itemgetter(1, 2))) #先以成績再以年齡排序資料 測試結果: ['apple', 'melon', 'orange'] ['melon', 'apple', 'orange'] [('Bill', 'B', 15), ('Danny', 'A', 14), ('Geoff', 'B', 14)] [('Danny', 'A', 14), ('Bill', 'B', 15), ('Geoff', 'B', 14)] [('Danny', 'A', 14), ('Bill', 'B', 15), ('Geoff', 'B', 14)] [('Danny', 'A', 14), ('Geoff', 'B', 14), ('Bill', 'B', 15)] [('Danny', 'A', 14), ('Geoff', 'B', 14), ('Bill', 'B', 15)] sorted ()函式 3/4
  • 27.  如果要排序的物件是class object的話,也可以使用operator模組中的 attrgetter() 做為 key 函式 class Student: def __init__(self, name, grade, age): self.name = name self.grade = grade self.age = age def __repr__(self): return repr((self.name, self.grade, self.age)) students = [Student('Bill', 'B', 15), Student('Danny', 'A', 14), Student('Geoff', 'B', 14)] print(sorted(students, key = attrgetter('grade'))) #比成績 print(sorted(students, key = attrgetter('grade', 'age'))) #先比成績再比年齡 測試結果: [('Danny', 'A', 14), ('Bill', 'B', 15), ('Geoff', 'B', 14)] [('Danny', 'A', 14), ('Geoff', 'B', 14), ('Bill', 'B', 15)] 註:有關類別宣告後續單元再介紹 sorted ()函式 4/4
  • 28.  enumerate() 函式用來自可叠代對象 (如串列、元組、集合等) 中依序 列舉出元素值,並加以順序編號  enumerate(sequence, [start = 0])  start 為將列舉所取得資料進行編號之起始值,預設值為 0  enumerate 多用於在 for 循環中得到計數,利用它可以同時獲得索引 和值,即需要 index 和 value 值的時候可以使用 programmer = {'Jack', 'Sam', 'Susan', 'Janice'} for index, name in enumerate(programmer, start = 1): print('%s. %s' %(index, name)) 測試結果: 1. Susan 2. Sam 3. Janice 4. Jack enumerate()函式
  • 29.  遊戲規則  由玩家 (X) 與電腦 (O) 輪流對奕,隨機決定先手  先連成⼀線者勝出  電腦落子策略 1. 檢查棋盤,如有決勝點即落子 2. 檢查棋盤,如存在對手決勝點,落子阻斷 3. 依據棋盤空格優先序落子 1) 四個角落空格 2) 中間空格 3) 四個邊空格 應用實例:井字棋遊戲 1/8
  • 30.  建立board串列儲存對奕資料,元素 1 ~元素 9 對應井字棋盤九格,元 素 0 沒使用;'X'表示玩家落子,'O'表示電腦落子,' '表示空格 import random board = [' ' for x in range(10)]  printBoard() 自訂函式用來顯示井字棋 def printBoard(): print(' ' + board[1] + '|' + board[2] + '|' + board[3] + ' ') print('--+-+--') print(' ' + board[4] + '|' + board[5] + '|' + board[6] + ' ') print('--+-+--') print(' ' + board[7] + '|' + board[8] + '|' + board[9] + ' ') 應用實例:井字棋遊戲 2/8 1 2 3 4 5 6 7 8 9
  • 31.  isWinner(bo, c)自訂函式用來檢查是否連線,有連線時回傳 True  bo 井字棋對奕資料  c 為棋子符號,'X'代表玩家,'O'代表電腦 def isWinner(bo, c): return (bo[1]==bo[2]==bo[3]==c) or (bo[4]==bo[5]==bo[6]==c) or (bo[7]==bo[8]==bo[9]==c) or (bo[1]==bo[4]==bo[7]==c) or (bo[2]==bo[5]==bo[8]==c) or (bo[3]==bo[6]==bo[9]==c) or (bo[1]==bo[5]==bo[9]==c) or (bo[3]==bo[5]==bo[7]==c)  isBoardFull(bo)自訂函式用來檢查井字棋是否填滿了 def isBoardFull(): return board.count(' ') == 1 #只剩⼀個空格時(元素0),表示棋盤已填滿  selectRandom(li)自訂函式用來自li串列中隨機挑選⼀個元素值 def selectRandom(li): r = random.randrange(0, len(li)) return li[r] 應用實例:井字棋遊戲 3/8
  • 32.  playerTurn()自訂函式為玩家回合處理作業,若玩家輸入的棋盤位 置編號為空格則落子'X',否則重新輸入 def playerTurn(): while True: try: move = int(input('Select a position to place an 'X' (1-9): ')) if move > 0 and move < 10: if (board[move] == ' '): board[move] = 'X' break else: print('Sorry, this space is occupied!') else: print('Please type a number within the range!') except: print('Please type a number!') printBoard() #顯示棋盤目前結果 應用實例:井字棋遊戲 4/8 1 2 3 4 5 6 7 8 9
  • 33.  evaluateMove()自訂函式為電腦回合計算最佳落子位置  落子優先序:連線決勝點、阻斷對手連線點、四個角落、中間、四個邊 def evaluateMove(): candiate = tuple([x for x, c in enumerate(board) if c == ' ' and x != 0]) for let in ('O', 'X'): #檢查決勝點及阻斷對手決勝點 for i in candiate : boardCopy = board[:] #複製棋盤以便測試 boardCopy[i] = let if isWinner(boardCopy, let): return i cornersOpen = [] for i in candiate : if i in (1, 3, 7, 9): cornersOpen.append(i) if len(cornersOpen) > 0: #選擇四個角落位置 return selectRandom(cornersOpen) 應用實例:井字棋遊戲 5/8
  • 34. if 5 in candiate: #選擇中間位置 return 5 edgesOpen = [] for i in candiate: if i in (2, 4, 6, 8): edgesOpen.append(i) if len(edgesOpen) > 0: #選擇四邊位置 return selectRandom(edgesOpen)  computerTurn()自訂函式為電腦回合處理作業 def computerTurn(): move = evaluateMove() board[move] = 'O' print('Computer placed an 'O' in position', move) printBoard() #顯示棋盤目前結果 應用實例:井字棋遊戲 6/8
  • 35.  game()自訂函式為遊戲流程控制作業 def game(turn): while True: if (turn): playerTurn() #玩家回合 turn = 1 - turn #換手 if isWinner(board, 'X'): print('You won this time!') break; else: computerTurn() #電腦回合 turn = 1 - turn #換手 if isWinner(board, 'O'): print('Computer won this time!') break; if isBoardFull(): print('Tie Game!') break; 應用實例:井字棋遊戲 7/8
  • 36.  程式主流程 while True: print('Welcome to Tic Tac Toe!', end = ', ') turn = random.randint(0, 9) % 2 #隨機決定先手,0電腦, 1玩家 if (turn == 1): print('玩家先下') printBoard() #畫出空棋盤 else: print('電腦先下') game(turn) answer = input('Do you want to play again? (Y/N)') if answer.lower() == 'y' or answer.lower == 'yes': board = [' ' for x in range(10)] print('-----------------------------------') else: break 應用實例:井字棋遊戲 8/8