基礎 python 程式設計

Similar documents
数据结构与算法 - Python基础

Python a p p l e b e a r c Fruit Animal a p p l e b e a r c 2-2

CHAPTER VC#

新・明解Python入門

Microsoft PowerPoint - C_Structure.ppt

Spyder Anaconda Spyder Python Spyder Python Spyder Spyder Spyder 開始 \ 所有程式 \ Anaconda3 (64-bit) \ Spyder Spyder IPython Python IPython Sp

Microsoft Word - ACG chapter00c-3ed.docx

C/C++ - 函数

Excel VBA Excel Visual Basic for Application

840 提示 Excel - Excel -- Excel (=) Excel ch0.xlsx H5 =D5+E5+F5+G5 (=) = - Excel 00

Microsoft Word - ACL chapter02-5ed.docx

C/C++ - 字符输入输出和字符确认

C/C++ - 文件IO

C/C++语言 - C/C++数据

投影片 1

untitled

<4D F736F F D DA5BFA6A1C476C1C92DBEC7ACECB8D5A8F728B57BB35D292E646F63>

Microsoft PowerPoint - Class2.pptx

Microsoft PowerPoint - chap3

科学计算的语言-FORTRAN95

CC213

3.1 num = 3 ch = 'C' 2

C/C++程序设计 - 字符串与格式化输入/输出

目次 CONTENTS 2 1 乘法公式與多項式 二次方根與畢氏定理 因式分解 一元二次方程式

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1

C 語言—陣列及字串

WWW PHP Comments Literals Identifiers Keywords Variables Constants Data Types Operators & Expressions 2

C/C++语言 - 运算符、表达式和语句

3. 給 定 一 整 數 陣 列 a[0] a[1] a[99] 且 a[k]=3k+1, 以 value=100 呼 叫 以 下 兩 函 式, 假 設 函 式 f1 及 f2 之 while 迴 圈 主 體 分 別 執 行 n1 與 n2 次 (i.e, 計 算 if 敘 述 執 行 次 數, 不

PowerPoint Presentation

第5章修改稿

Java 程式設計初階 第 5 章:基本輸出入 & 流程控制

Microsoft Word - 投影片ch03

Ps22Pdf

Microsoft PowerPoint - VB3

C/C++基礎程式設計班

碩命題橫式

Microsoft PowerPoint - OPVB1基本VB.ppt

四川省普通高等学校

主程式 : public class Main3Activity extends AppCompatActivity { ListView listview; // 先整理資料來源,listitem.xml 需要傳入三種資料 : 圖片 狗狗名字 狗狗生日 // 狗狗圖片 int[] pic =new

FY.DOC

新・解きながら学ぶJava

Microsoft PowerPoint - CH02 Introduction to C++ Programming_輸入與輸出 [相容模式]

untitled

Microsoft PowerPoint - Class5.pptx

標題版面配置

4

ACI pdf

Microsoft PowerPoint - Lecture7II.ppt

Microsoft PowerPoint - 06_迴圈2.pptx

運算子多載 Operator Overloading

Python 與中文處理

WWW PHP

單步除錯 (1/10) 打開 Android Studio, 點選 Start a new Android Studio project 建立專案 Application name 輸入 BMI 點下 Next 2 P a g e

資料結構之C語言重點複習

Microsoft PowerPoint - 02_運算.pptx

Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc

( ) Wuhan University

4. 债 务 人 明 确 表 示 撞 行 拖 欠 的 债 务, 这 在 法 律 上 将 引 起 ( ) 人. 诉 讼 时 效 的 中 止 日. 诉 讼 时 效 的 中 黯 C. 诉 讼 时 效 的 延 长 D. 法 定 诉 讼 时 敷 黯 爵 的 改 变 5. 职 工 代 表 大 会 是 国 有 企

Microsoft Word - 第3章.doc

Java 程式設計入門

Microsoft Word - C-pgm-ws2010.doc

Slide 1

PowerPoint プレゼンテーション

Microsoft Word - 09.數學 docx

C 1

0 0 = 1 0 = 0 1 = = 1 1 = 0 0 = 1

C C

C

C/C++基礎程式設計班

1 Framework.NET Framework Microsoft Windows.NET Framework.NET Framework NOTE.NET NET Framework.NET Framework 2.0 ( 3 ).NET Framework 2.0.NET F

<4D F736F F D B0D3B77EC3FEA7DEC3C0C476C1C9A5BFA6A1B8D5C3442DB57BA6A1B35DAD702DBEC7ACEC2E646F6378>

PowerPoint Presentation

三維空間之機械手臂虛擬實境模擬

投影片 1

lnag_ch_v2.01.doc

PowerPoint 簡報

Microsoft Word - Delta Controller ASCII_RTU_TC

投影片 1

p.2 1. a. b. c. (i) (ii)

C/C++ 语言 - 循环

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc

######## First set of commands x <- 0.5; y <- 0 if (x>3) y <- 1 else y <- 2 ######## Second set of commands x <- 0.5; y <- 0 if (x>3) y <- 1 else ###

. (A) (B) (C) A (D) (E). (A)(B)(C)(D)(E) A

Microsoft PowerPoint - CH07 Arrays and Vectors [相容模式]

02

Microsoft Word C-A卷.docx

PowerPoint 簡報

第二章

運算子多載 Operator Overloading

Learn_Perl 3-02.pdf

<5B BECBB0EDB8AEC1F25D312D34B0AD5FC3E2BCAEBCF6BEF7C0DAB7E F31702E504446>

coverage2.ppt

Historical Fund Prices_TC_mt_2017.pdf

電腦做什麼事~第七章

CC213


C/C++ - 字符串与字符串函数


Transcription:

計概二 基礎 python 程式設計 吳維漢中央大學數學系

Python 1989 年底由荷蘭人 Guido van Rossum 開始建構 為解譯式程式語言 (interpreter) 2000 : python 2.0 2008 : python 3.0 2016 年二月在 TIOBE 程式語言排名榜中為居於第五位 1 簡介

Why Python? 容易使用 (easy to use) 很快寫出來 (expressive) 可讀性高 (readable) 完備 (complete) 跨平臺 (cross-platform) 免費 (free) 2 簡介

Why not Python 執行效率不是很高 程式庫不是最多 編譯過程不會檢查變數型別 3 簡介

The Zen of Python 美麗優於醜陋 Beautiful is better than ugly. 明講優於暗喻 Explicit is better than implicit. 簡單比複雜好 Simple is better than complex. 複雜又比繁澀佳 Complex is better than complicated. 程式可讀性很重要 Readability counts. 4 簡介

Python 一些資料型別 整數 (integers): 0, -343, 12039383838383883838 浮點數 (floats): 3., 123e23, 0.1e-3 複數 (complex numbers):1+2j, -j, 2.3 + 1.2j 布林數 (booleans):true, False >>> x = 23 # x 為整數 >>> print(x) >>> x = 1+2j # 改為複變數 >>> print(x) 5 基本資料型別

mutable 與 immutable 型別 mutable : 資料可以被更動串列 (list), 集合 (set), 字典 (dictionary) immutable : 資料不可以被更動整數 (integer), 浮點數 (float), 複數 (complex), 字串 (string),... 6 mutable 與 immutable 型別

immutable 與儲存空間配置 # a 儲存空間內存 3 a >>> a = 3 3 # b 與 a 共用儲存空間 a b >>> b = a 3 # a 在新的儲存空間存 4, 舊空間為 b 使用 >>> a = b+1 a 4 b 3 7 immutable 型別

mutable 與儲存空間配置 # a 儲存 1, 2 兩個元素 >>> a = [ 1, 2 ] # b 與 a 共用儲存空間 >>> b = a # b 增加一個元素 3, 也影響 a >>> b.append(3) a 1 2 a b 1 2 a 1 2 b 3 # b 在新的儲存空間儲存 5 >>> b = [ 5 ] a 1 2 3 b 5 8 mutable 型別

python 的資料型別 type 型別 M/I 樣式 int 整數 I 23, -234 float 浮點數 I 1.2, -234e-12 boolean 布林數 I True, False complex 複數 I 1-j, -2.3+2j str 字串 I "hello", "123" list tuple 串列元組 M I [ 2, "c", [ -2.2, "1+j" ] ] ( 1, ), ( "2", [ 2, "j" ] ) set frozenset 集合凍集合 M I { 12, "ab" }, set ( [1,2] ) frozenset ( [ 12, "ab"] ) dict 字典 M { "ncu":" 中大 ", " 中大 ":"ncu" } bytearray 位元組序列 M bytearray(b cat ) bytes 位元組序列 I b cat, b([99,97,116]) 9 基本資料型別

數學運算子 符號 運算子 範例 + - * / 加減乘除 3+4 = 7 % // ** += -= *= /= %= << >> < > <= >= ==!= 餘數運算 floor 除法指數運算加減... 複合運算位元左右位移比較大小 7%3 = 1 7//3 = 2, 7.5//3 = 2 3**2 = 9 a+=4 --> a = a + 4 1<<2 = 4, 7>>1 = 3 4>3, x <= X 10 運算子

整數 無位數限制 兩整數間的加, 減, 乘等計算結果皆為整數 使用 / 除法的計算結果為浮點數 使用 // 除法 (floor division) 的計算結果為整數 int("123") 可將字串轉為整數 int(123.45) 會浮點數的小數部份轉為整數 round(a) 使用偶數進位法 (round-to-even) round(2.5) = 2,round(1.5) = 2 11 整數

二進位, 八進位, 十六進位整數 0x11 --> 十六進位 11 0o11 --> 八進位 11 0b11 --> 二進位 11 將 a 整數轉為十六進位, 八進位, 二進位字串 hex(a), oct(a), bin(a) 將各種進位數字串轉為 10 進位數字 int( 0x11,16), int( 0o11,8), int( 0b11,2) 將各種進位數字串轉為 10 進位數字 int(hex(11),16) = 11, int(oct(11),8) = 11 int(bin(11),2) = 11 12 整數

浮點數 雙精確浮點數 有截去誤差 (round-off error) 0.1 + 0.2 = 0.30000000000000004 round(2.15, 1) = 2.1 # 取到小數點後第一位 round(2.25, 1) = 2.2 # 取到小數點後第一位 2.15+0.01 不等於 2.16 實際十進位數字 >>> from decimal import Decimal >>> Decimal(0.1) Decimal( 0.1000000000000000055511151231257...015625 ) 13 浮點數

數字運算函式 abs, divmod, float, hex, max, min, oct, pow, oct, bin, round 使用 math 函式庫 包含 :sin, cos, tan, pi, exp, log10, log, pow, floor,... dir (math) 或 help (math) 取得用法 使用方式 : >>> import math >>> a = 2 * math.pi >>> print(a) >>> from math import * >>> b = 2 * pi >>> print(b) 14 數字運算

串列 :list 由排成一列的元素組成 元素可包含各種型別 :[ 1, "abc", 3+2j, 5.6 ] 串列元素也可以為串列 : >>> b = [ [ 1, 2-1j ], [ 3+2j, 4 ] ] 串列長度 :len ( 串列 ) len([1,"abc",5.6]) = 3 len([ [ 1, 2-1j ], [ 3+2j ] ]) = 2 空串列為 [] 15 串列

串列下標 ( 一 ) 串列元素可使用陣列下標取得 a = [ 1, " 中大 ", 3+2j, 5.6 ] 串列 a 正向下標逆向下標 1 " 中大 " 3+2j 5.6 0 1 2 3-4 -3-2 -1 則 a[1] = 1, a[-1] = 5.6, a[1][1] = " 大 " 二維串列 : >>> b = [ [ 1, 2-1j ], [ 3+2j, 4 ] ] 則 b[0][1] = 2-1j, b[1][1] = 4 16 串列

串列下標 ( 二 ) 若 a = [ 1, " 中大 ", 3+2j, 5.6 ] a[i:j] 取得 a[i], a[i+1],..., a[j-1] 間的 j-i 個元素 a[1:3] = [ 中大, (3+2j) ], a[0:2] = [ 1, " 中大 " ] a[i:] a[:j] 複製由 a[i] 到末尾的元素 複製由 a[0] 到 a[j-1] 的元素 a[i:j:k] 取得 a[i], a[i+k], a[i+2k],, 下標不超過 j-1 a[2:] = [ (3+2j), 5.6 ] a[0:] = [ 1, " 中大 ", 3+2j, 5.6 ] a[0:3:2] = 中大 17 串列

更改串列 ( 一 ) 若 a = [ 1, 中大, 3+2j, 5.6 ] 串列為 mutable: 可以自由變更串列元素 >>> a[2] = math >>> a [1, 中大, math, 5.6] 串列複製 >>> b = a[:] # b 與 a 為相同內容的兩串列 >>> a[2] = math >>> b b = [ 1, 中大, (3+2j), 5.6 ] 串列指定 >>> b = a # b 與 a 為同一串列 >>> a[2] = math >>> b [1, 中大, math, 5.6] 18 串列

更改串列 ( 二 ) 若 a = [ 1, 中大, 3+2j, 5.6 ] 更改串列部份元素 >>> a[1:3] = [ aa, bb, 8 ] >>> a [1, aa, bb, 8, 5.6] 接到末尾 >>> a[len(a):] = [ 7, 8 ] >>> a [ 1, 中大, (3+2j), 5.6, 7, 8 ] 放在前端 >>> a[:0] = [ 7, 8 ] >>> a [ 7, 8, 1, 中大, (3+2j), 5.6 ] 保留頭尾 >>> a[1:-1] = [] >>> a [ 1, 5.6 ] 19 串列

串列合成與元素複製 使用 + 合成兩串列 >>> a = [ 1, 2, 3 ] + [ 4, 5 ] >>> a [1, 2, 3, 4, 5] 使用 * 複製元素 >>> a = [ 1 ] * 3 >>> a [1, 1, 1] 可以合併使用 + * 製造串列 >>> a = [ 1 ] * 3 + [ 4, 5 ] * 2 >>> a [1, 1, 1, 4, 5, 4, 5] 20 串列

list 進階設定方式 使用 range 物件 : >>> list(range(4)) [0, 1, 2, 3] >>> list(range(1,4)) [1, 2, 3] >>> list(range(1,5,2)) [1, 3] list comprehension >>> [ x for x in range(4) ] [0, 1, 2, 3] >>> [ x*x for x in range(4) ] [0, 1, 4, 9] >>> [ [ x, x*x ] for x in range(4) ] [[0, 0], [1, 1], [2, 4], [3, 9]] >>> [ [ x, x*x ] for x in range(4) if x%2 ] [[1, 1], [3, 9]] 21 串列

list comprehension : 範例 >>> [ (x//2+1)*2 for x in range(8)] [2, 2, 4, 4, 6, 6, 8, 8] >>> [ [x,y] for x in range(3) for y in range(2)] [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1]] >>> # a 為 25 以下的合數, b 為 25 以下的奇數 >>> a = [j for i in range(2,6) for j in range(i*2,26,i)] >>> b = [ x for x in range(2,26) if x not in a ] >>> b [2, 3, 5, 7, 11, 13, 17, 19, 23] 22 串列

設定一到三維串列 設定 3 個元素一維串列 >>> a = [ None ] * 3 [None, None, None] None 為 python 的常數, 用來表示數值尚未設定 設定 3 2 個元素二維串列 >>> a = [ [None]*2 for x in range(3) ] [[None, None], [None, None], [None, None]] 設定 3 2 4 個元素三維串列 >>> a = [[[None]*4 for j in range(2)] for k in range(3)] [[[None, None, None, None], [None, None, None, None]],[[None, None, None, None], [None, None, None, None]],[[None, None, None, None], [None, None, None, None]]] 23 串列

二維串列 設定 3 2 個元素二維串列 正確方式 : 使用 list comprehension >>> a = [ [None]*2 for x in range(3) ] [[None, None], [None, None], [None, None]] >>> a[2][1] = 5 >>> a [[None, None], [None, None], [None, 5]] 錯誤方式 : 使用 * >>> b = [ [None]*2 ] * 3 [[None, None], [None, None], [None, None]] >>> b[2][1] = 5 >>> b [[None, 5], [None, 5], [None, 5]] NOTE: b 二維串列內的每個一維序列都使用同樣的記憶空間 24 串列

串列複製的空間配置 ( 一 ) 複製 immutable 物件 a = [1,3] b = a*2 = [1,3,1,3] 複製 mutable 物件 c = [1,3] d = [c]*2 = [[1,3],[1,3]] >>> a[0] is b[0] and a[0] is b[2] True >>> a[1] is b[1] and a[1] is b[3] True >>> a[0]=5 >>> a >>> b [5,3] b=[1,3,1,3] >>> c is d[0] and c is d[1] True >>> c.append(5) >>> c [1,3,5] >>> d [[1,3,5],[1,3,5]] 25 串列

串列複製的空間配置 ( 二 ) a = [1]*2 = [1,1] a 1 1 不同空間 b = [ [1,2] ]*3 = [ [1,2],[1,2],[1,2] ] c = [1,2]*3 = [1,2,1,2,1,2] b 相同空間 [1,2] [1,2] [1,2] 相同空間 c 1 2 1 2 1 2 各個佔有不同空間 26 串列

tuple tuple 為元素不可更動的 list tuple 使用小括號 >>> a = ( 3, x, 2.4 ) >>> a[1] x >>> a[0] = 4 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: tuple object does not support item assignment 一個元素的 tuple 須在其後加逗點 >>> (3+2,) (5,) >>> (3+2) 5 空 tuple:() 27 tuple 型別

tuple 設定方式 使用 tuple 將 list 換為 tuple: >>> a = [ 3, 4 ] >>> b = tuple(a) >>> b (3, 4) 使用 list comprehension 後轉型為 tuple >>> c = tuple( [ x*x for x in range(5) ] ) >>> c (0, 1, 4, 9, 16) 可使用 + 或 * 產生 tuple >>> a = (2,3) + (5,) >>> a (2, 3, 5) >>> b = b + ( x,) >>> b (2, 3, 5, x ) >>> (3,1) * 2 (3, 1, 3, 1) NOTE: 若 a 為 tuple, 也可使用 list(a) 產生串列 28 tuple 型別

tuple : 使用包裝設定資料 快速設定資料 : >>> ( one, two, three ) = ( 1, 2, 3 ) >>> three 3 >>> a = ( 4, 5, 6 ) >>> ( four, five, six ) = a >>> six 6 可省略括號 : >>> one, two = 1, 2 >>> two 2 >>> # 對調元素資料 >>> x, y = 3, 4 >>> x, y = y, x 29 tuple 型別

星號式子語法 星號式子語法 : >>> ( a, *b ) = ( 1, 2, 3, 4 ) >>> a 1 >>> b [2, 3, 4] >>> a, b (1, [2, 3, 4]) >>> *a, b, c = [ 1, 2, 3, 4 ] >>> a, b, c ([1, 2], 3, 4) NOTE:(1) 一個設定式子不可超過一個以上的星號 (2) 在指定式時, 星號語法僅能用來被設定 ( 指定左側 ) 30 tuple 型別

字串 使用單引號或雙引號夾住的文字 : abc, "abc", "Tom s" 多列字串使用三個引號 : """ 中央大學數學系 """ 字元序列 sequences of (utf-8) characters >>> x = abc 則 x[0]= a, x[1]= b, x[2]= c >>> y = 中央大學 則 y[0]= 中, y[1]= 央 >>> len(y) 字串長度 相等字元 : m, \155, \x6d 特殊字元 : \ 單引號 \\ 反斜線 \ooo: 八進位 ooo 字元 \" 雙引號 \b 退後字元 \xhh:16 進位 hh 字元 \n 換行字元 \t 定位字元 31 字串

基本字串處理 字串合成 : x = " 中央大學 " + " " + " 數學系 " 字串乘法 : x = " 貓 " * 3 = " 貓貓貓 " 分解為字元序列 : >>> list( 中央 math ) [ 中, 央, m, a, t, h ] 字元序列 : 字串 a 正向下標逆向下標 中央大學數學系 0 1 2 3 4 5 6-7 -6-5 -4-3 -2-1 a[-1] = 系 ( 末尾元素 ) a[0] = a[-7] = 中, a[1] = a[-6] = 央... 字串為 immutable: 無法更改字串內容 >>> a = " 數學系 " >>> a[2] = " 人 " # 錯誤, 字串內容不能被更改 32 字串

字串處理 : 複製子字串 x[i:j] 可複製 x[i] 到 x[j-1] 之間的字元 >>> a = " 中央大學 math" 則 a[2:4] = 大學, a[4:-1] = mat a[i:] 複製由 a[i] 到末尾的字元 a[:j] 複製由 a[0] 到 x[j-1] 的字元 a[i:j:k] 取得 a[i], a[i+k], a[i+2k], 直到 a[j-1] a[4:] = math, a[0:] = a[:] = 中央大學 math a[0:3:2] = 中大 逆向複製子字串 a[-1:-5:-1] = htam a[-1::-1] = a[::-1] = htam 學大央中 字串長度 :len ( 字串 ) len(" 中央大學 math") = 7 33 字串

字串分解成字串串列 字串分解成字串串列 list( 字串 ) >>> list(" 中央大學 ") [ 中, 央, 大, 學 ] 字串.split( 分隔字串, 數量 ) >>> " 中 - 央 - 大 - 學 ".split("-") [ 中, 央, 大, 學 ] >>> " 中 - 央 - 大學 ".split("-",2) [ 中, 央, 大學 ] 字串.split() : 去除字串間的所有空格 >>> "a bc d".split() # a bc d 間有兩個空格 [ a, b, c ] >>> "a bc d".split(" ") # a bc d 間有兩個空格 [ a,, b,, c ] 34 字串

字串串列合併為字串 字串串列轉成字串 分隔字串.join( 串列 ) >>> "-".join([ 中, 央, 大, 學 ]) 中 - 央 - 大 - 學 >>> "".join([ 中, 央, 大, 學 ]) 中央大學 NOTE:.join( list( 字串 ) ) = 原字串 35 字串

字元在萬國碼的編碼位置 chr ( 字元 ) 與 ord ( 數字 ) >>> ord( a ) # a 在萬國碼 (unicode) 內的編碼位置 97 >>> chr(97) # 在萬國碼中編碼位置為 97 的字元 a >>> ord( 中 ) # 中 在萬國碼內的編碼位置 20013 >>> chr(20013) # 在萬國碼編碼位置為 20013 的字元 中 >>> [ ord(x) for x in " 中央 "] [20013, 22830] >>> "".join( [chr(x) for x in [20013, 22830]]) 中央 >>> [ chr(x+ord( a )) for x in range(5) ] [ a, b, c, d, e ] >>> "".join([ chr(x+ord( a )) for x in range(26)]) abcdefghijklmnopqrstuvwxyz 36 字串

字串數字轉字串 float( 字串數字 ) >>> float("3.14") 3.14 int( 字串數字, 進位方式 ) >>> int("24") 24 >>> int("12",8) # 八進位的 12 10 >>> int("12",6) # 六進位的 12 8 >>> int( ff,16) # 十六進位的 ff 255 37 字串

去除兩側的空白字元 空白字元 >>> import string # 輸入字串檔 >>> string.whitespace # 空白字元 \t\n\r\x0b\x0c foo 為字串 foo.strip() >>> x = " 中央大學數學系 " >>> x.strip() 中央大學數學系 >>> x.lstrip() 中央大學數學系 NOTE: 原 foo 字串不會變更 foo 去除前後兩側空白字元後存到新字串 foo.lstrip() foo 去除左側空白字元後存到新字串 foo.rstrip() foo 去除右側空白字元後存到新字串 38 字串

去除兩側多餘的字元 foo 與 bar 皆為字串 foo.strip(bar) 去除 foo 左右兩側在 bar 字串內的字元存到新字串 foo.lstrip(bar) 去除 foo 左側在 bar 字串內的字元後存到新字串 foo.rstrip(bar) 去除 foo 右側在 bar 字串內的字元後存到新字串 >>> x = "www.ncu.edu.tw" >>> x.strip("wt.") ncu.edu >>> y = x.rstrip("wt.") >>> y www.ncu.edu >>> x www.ncu.edu.tw 39 字串

搜尋子字串的位置 若 foo 與 bar 為字串, 則 foo.find(bar) 在 foo 字串搜尋 bar 字串出現的下標位置 foo.find(bar,a,b) 在 foo[a:b] 內找尋 bar 字串出現的下標位置 foo.rfind(bar) 在 foo 字串搜尋 bar 字串所出現的最高下標位置 foo.rfind(bar,a,b) 在 foo[a:b] 找尋 bar 字串所出現的最高下標位置 >>> x = "www.ncu.edu.tw" >>> x.find("ncu") 4 >>> x.find("ncu",5) -1 >>> x.rfind("w") 13 NOTE: 若未搜尋, 則回傳 -1 40 字串

計算子字串出現的次數 若 foo 與 bar 為字串, 則 foo.count(bar) 在 foo 字串找尋 bar 字串出現的次數 foo.count(bar,a,b) 在 foo[a:b] 內找尋 bar 字串出現的次數 >>> x = "www.ncu.edu.tw" >>> x.count("w") 4 >>> x.count("ww") 1 >>> x.count("ncu") 1 >>> x.count("ncu",5) 0 41 字串

檢查字串是否有起始或結束的子字串 若 foo 為字串, bar 為字串或為內含字串的 tuple, 則 foo.startswith(bar) foo.endswith(bar) 範例 : x = "www.ncu.edu.tw", 則 檢查 foo 字串是否有以 bar 字起始的子字串, 回傳 True 或 False 檢查 foo 字串是否有以 bar 字結束的子字串, 回傳 True 或 False foo.startswith(bar,a,b) 檢查 foo[a:b] 字串是否有以 bar 起始的子字串, 回傳 True 或 False foo.endswith(bar,a,b) 檢查 foo[a:b] 字串是否有以 bar 結束的子字串, 回傳 True 或 False x.startswith("www") ---> True x.startswith("ncu",3) ---> False x.startswith("ncu",4) ---> True x.endswith(("tw","cn")) ---> True x.endswith(("kr","cn","jp"))---> False 42 字串

逆轉字串 若 foo 為字串, 則 foo[::-1] >>> x = " 中央大學 " >>> x[::-1] 學大央中 >>> x[0:2][::-1] 央中 >>> x = "web1.nsc.gov.tw" >>> ".".join( [ y[::-1] for y in x.split(".") ] ) 1bew.csn.vog.wt.join(reversed(foo)) >>> x = " 數學系 " >>>.join(reversed(x)) 系學數 NOTE: reversed( 字串 ): 將字串逆轉存成字元迭代器 (iterator) 43 字串

取代字串內的子字串 若 foo, old, new 為字串, 則 foo.replace(old,new): 將 foo 內 old 全部改為 new >>> x = "www.ntu.edu.tw" >>> x.replace("ntu","ncu") www.ncu.edu.tw >>> x.replace("w","z") zzz.ncu.edu.tz foo.replace(old,new,n): 將 foo 內前 n 個 old 全部改為 new >>> x = "www.ntu.edu.tw" >>> x.replace("w","y",3) yyy.ncu.edu.tw NOTE: 字串為 immutable 物件, 取代僅會產生新字串, 原有字串不會變更 44 字串

變更字串字母大小寫 若 foo 為字串, 則 foo.upper() 將 foo 內的字母轉成大寫 foo.lower() 將 foo 內的字母轉成小寫 foo.title() 將 foo 內的每一個字的第一個字母轉成大寫 >>> x = "My name is Tom." >>> x.upper() MY NAME IS TOM. >>> x.lower() my name is tom. >>> x.title() My Name Is Tom. 45 字串

判斷字串內容類型 若 foo 為字串, 則 foo.isdigit() 判斷 foo 是否全為數字 foo.isalpha() 判斷 foo 是否全為英文字母 foo.isalnum() 判斷 foo 是否全為英文字母或數字 foo.isupper() 判斷 foo 的字母是否全為大寫 foo.islower() 判斷 foo 的字母是否全為小寫 foo.islower() 判斷 foo 每個字的首個英文字母是否全為大寫 foo.isspace() 判斷 foo 是否全為空白字元 範例 : "123".isdigit() ---> True "123num".isalnum() ---> True "123num".isalpha() ---> False "My Age Is 23.".istitle() ---> True "The Year Is In 2010s.".istitle() ---> False 46 字串

format 格式輸出 使用 format 設定輸出格式 : >>> "{}/{}/{}".format( 1977,8,10) 1977/8/10 >>> "{2} 系 {1} 學院 {0} 大學 ".format(" 中央 "," 理 ", " 數學 ") 數學系理學院中央大學 format 的輸出為字串, 類似 C 語言的 sprintf: >>> a = {} 為 {} 元.format( apple,234) >>> a apple 為 234 元 47 格式輸出

字串的輸出格式 ( 一 ) 設定輸出位置 : {0},{1},,{n} >>> "{0} 大學 {1} 學院 {2} 系 ".format(" 中央 "," 理 "," 數學 ") 中央大學理學院數學系 >>> "{2} 系 {1} 學院 {0} 大學 ".format(" 中央 "," 理 "," 數學 ") 數學系理學院中央大學 設定各種輸出型式 : 寬度, 精度, 對齊方式等 : >>> "Total : {0:5} 元 ".format(234) Total : 234 元 >>> "Total : {0:#>5} 元 ".format(234) Total : ##234 元 >>> "Total : {0:#<7.2f} 元 ".format(23.4567) Total : 23.46## 元 48 格式輸出

整數的輸出格式 ( 二 ) 填補字元, 對齊, 寬度 >>> "{0:#<7}{1:@>7}{2:*^8}".format(12345,67890,1345) 12345##@@67890**1345** NOTE : 填補字元在使用對齊時才能使用 進位方式 >>> "{0:#<4}-{0:08b}-{0:#>4x}".format(12) 12##-00001100-###c NOTE : b 二進位,o 八進位,x/X 16 進位 正負號, 對齊 >>> "{0:0=+5}".format(12) +0012 >>> "{0:#>+5} {0:#=+5}".format(12) ##+12 +##12 逗點 >>> {:#>20,}.format(1234567890) #######1,234,567,890 49 格式輸出

浮點數的輸出格式 小數點型式 : >>> {:>f}.format(12.239013433) # 預設小數點精度為 6 位 12.239013 >>> {:#>7.2f}.format(12.2390) # 以 7 格列印, 小數點後用 2 格 ##12.24 科學記號形式 >>> {0:e}{0:#>10.2e}{0:#>10.2E}.format(12.2390) 1.223900e+01##1.22e+01##1.22E+01 百分號形式 >>> {0:%}{0:#>.1%}{0:#>10.2%}.format(12.239) 1223.900000% 50 格式輸出

使用名稱參數輸出 使用名稱取代數字代號 : >>> {b} has {a:#>3} pts..format(a=99,b="tom") Tom has #99 pts. >>> x = "John" >>> {b} has {a:#>3} pts..format(a=2.3434,b=x) John has #99 pts. >>> {a:{f}{g}{x}.{y}f}.format(a=2.3434,f= #,g= >,x=5,y=2) #2.34 51 格式輸出

列印資料 :print 使用 print() 來列印資料 >>> print("a","b") a b NOTE: a b 之間自動空一格, 印完後自動換行 設定各資料間的分離字串 >>> print("a","b","c",sep="--") a--b--c 設定列印後的自動輸出串 >>> print("a","b","c",sep="--",end="##") a--b--c## NOTE: 預設的自動輸出字串為 "\n" 52 輸出與輸入

讀取資料 ( 一 ) 使用 input 來讀取整行資料 : >>> x = input("-> ") -> hello kitty >>> x hello kitty NOTE:input ( 字串 ) 的字串為輸入的提示字串 讀取一筆數字 : >>> a = int(input(" 輸入 > ") # int 用來轉型 輸入 > 30 >>> b = int(input(" 輸入 > ") # int 用來轉型 輸入 > 25 >>> print(a+b) 55 53 輸出與輸入

讀取資料 ( 二 ) 讀取一串數字 : >>> a, b, c = eval(input("-> ") ) -> 1.1, 2, 4 # 須用逗點隔開 >>> a+b+c 7.1 NOTE: 用一行方式讀取各種資料時, 須用逗點分開 讀取運算式 : >>> a = eval(input("-> ")) -> [ x*x for x in range(1,6) ] >>> a [1, 4, 9, 16, 25] NOTE: eval 函式用來計算字串式子的值, 例如 : >>> eval("3+4*5") 23 >>> eval("[ x**3 for x in range(1,5)]") [1, 8, 27, 64] 54 輸出與輸入

讀取資料 ( 三 ) 分解輸入的字串成串列 : >>> a = input("-> ").split(" ") -> hello kitty >>> a [ hello, kitty ] >>> b = input("-> ").split(" ") > 2 3 4 >>> b [ 2, 3, 4 ] 分解輸入的字串成數字串列 : >>> [ int(x) for x in input("-> ").split(" ") ] -> 2 3 4 [2, 3, 4] 計算輸入數值的平方和 : >>> sum( [ int(x) for x in input("-> ").split(" ") ] ) -> 2 3 4 9 55 輸出與輸入

邏輯式子 ( 一 ) Boolean 真假值 : 假 :False, None, 0, 0.0, 0j, "", [], (), {} 真 :True, 非假 比較大小 : == ( 等於 ),!= ( 不等於 ), >, >=, <, <= and ( 而且 ), or ( 或 ), not ( 非 ): 邏輯運算 >>> a = 3 ; b = 5 >>> a > 4 and b < 5 False >>> not ( a < 4 or b > 5 ) False >>> ( a > 4 and a < 7 ) 可寫成 ( 4 < a < 7 ) NOTE : 同一列若有多個式子可用分號隔開 56 邏輯式子

邏輯式子 ( 二 ) x is y, x is not y: 比較 x 與 y 是否為 ( 不 ) 同物件 >>> a = 3 ; b = a >>> a is b True >>> b = 4 ; >>> a is b False >>> c = [ 2 ] ; d = c >>> d is c True >>> c.append(5) >>> d is c True 57 邏輯式子

邏輯式子 ( 三 ) a in b, a not in b: 比較 a 是否 ( 不 ) 在 b 之中 >>> a = "cat" >>> t in a True >>> x not in a True >>> c = range(4) >>> 4 in c False >>> e = [1, 3, 5] ; f = 4 >>> f in e False >>> f not in e True 58 邏輯式子

流程控制 ( 一 ) A if C else B: 如果 C 為真則回傳 A 否則回傳 B >>> x = -3 >>> x if x > 0 else -x 3 if: if x > 3 : print(x) if x > 3 : print(x) # 冒號結束 # 縮排 NOTE: (1) if 之後需加冒號結束條件式 (2) if 之後要執行的式子, 若僅有一行, 可直接寫在同一行 若超過一行, 則需以縮排方式寫在下面 59 流程控制

流程控制 ( 二 ) if-elif-else: if x > 10 : print("x > 10") elif 5 <= x <= 10 : print("x in [5,10]") elif x > 3 : print("x in (3,5)") else : print("x <= 3") NOTE: 若問題不需 elif 或 else 可以省略, 同時 elif 數量不受限制 60 流程控制

流程控制範例 : 一元二次方程式的根 from math import * while True : a, b, c = ( int(x) for x in input("> ").split(" ") ) delta = b*b - 4*a*c if delta > 0 : r1 = (-b + sqrt(delta))/(2*a) r2 = (-b - sqrt(delta))/(2*a) elif delta == 0 : r1 = r2 = -b/(2*a) else : r1 = complex(-b/(2*a),sqrt(-delta)/(2*a)) r2 = complex(-b/(2*a),-sqrt(-delta)/(2*a)) print( "{0} x^2 + {1} x +{2} :".format(a,b,c),r1,r2 ) 61 流程控制

while 迴圈 ( 一 ) 當 A 為真, 重複執行 B 直到 A 為假 while A : B A while A : B 假 B 真 # 計算一到十的和 sum, x, n = 0, 1, 10 while x <= n : sum += x x += 1 print(sum) 62 迴圈

while 迴圈 ( 二 ) # 產生十個介於 [1,5] 間亂數存於串列內 from random import * c, x = ( 0, [] ) while c < 10 : # randint(a,b) 產生介於 [a,b] 的整數亂數 x.append(randint(1,5)) c += 1 print(x) NOTE: 以上 c 也等於 [ randint(1,5) for x in range(10) ] 63 迴圈

for 迴圈 ( 一 ) 由 A 中一一取出元素名為 a 後執行 B 直到 A 的元素取完為止 for a in A : B for a in A : B # 印出高度為 5 的金字塔 n = 5 for x in range(1,n+1) : * *** ***** ******* ********* print( " "*(n-x), "*"*(2*x-1) ) 64 迴圈

for 迴圈 ( 二 ) for 與 if 交錯使用 # 印出高度為 7 的鑽石 n = 7 h = n//2 + 1 for x in range(1,n+1) : if x <= h : print( " "*(h-x),"*"*(2*x-1),sep="" ) else : * *** ***** ******* ***** *** * print( " "*(x-h),"*"*(2*(n+1-x)-1),sep="" ) 65 迴圈

多層迴圈 迴圈內也可有迴圈 # 印出高度為 7 的交叉圖形 n = 7 for i in range(1,n+1) : for j in range(1,n+1) : if i == j or i+j == n+1 : print("*",end="") else : print(" ",end="") print() * * * * * * * * * * * * * NOTE: 以上 if... else... 可改用以下一列方式 : print( "*" if i==j or i+j==n+1 else " ", end ="") 66 迴圈

提前跳出迴圈 :break ( 一 ) 使用 break 提前跳離迴圈 : for a in A : C if B : break while A : for b in B : if C : break D if d in B : break E NOTE: 多層迴圈的 break 僅會跳離一層迴圈 67 迴圈

提前跳出迴圈 :break ( 二 ) # 當輸入的數字和為奇數時才跳出迴圈 while True : a = [ int(x) for x in input("> ").split(" ") ] s = sum(a) print( a, " 和為 ", " 奇數 " if s%2 else " 偶數 ") if ( s%2 ) : break 68 迴圈

提前進入下一個迭代 :continue ( 一 ) 使用 continue 可提早進入下一個迭代 while True : if A : continue B while True : if not A : B NOTE:continue 僅是提早進入下一個迭代, 並非 跳離迴圈 69 迴圈

提前進入下一個迭代 :continue ( 二 ) while True : sum = 0 b = [] for a in [ int(x) for x in input(">").split()] : if a < 0 : continue # 當 a 為負數, 提前進入下個迭代 b.append(a) sum += a print( "sum of", b, ":", sum ) > 2 3 4 1 sum of [2, 3, 4, 1] : 10 > 2 3-4 2 3 sum of [2, 3, 2, 3] : 10 70 迴圈

基礎程式設計 抽象數學與邏輯思維的實體應用 山裡有山路轉彎, 高山流水響潺潺 深山百鳥聲聲叫, 路上行人步步難 勸君莫作雲遊客, 孤身日日在山間 人人說道華山好, 我道華山第八山 山山八裡山第有山華道轉路山好我彎高山華道說響水流山間人人潺潺深山在日日身聲聲鳥百雲遊客孤叫路上行作莫君勸難步步人 迴圈與條件式的交織結合 71 基礎程式設計

lambda 函式 : 簡易函式定義方式 lambda 函式 : # 單參數函數 : 平方 f = lambda x : x*x for x in range(5) print(f(x),end=" ") 0 1 4 9 16 g = lambda x : (x,x+1,x+2) for x in range(3) print(g(x),end=" ") (0, 1, 2) (1, 2, 3) (2, 3, 4) # 多參數函數 : 九九乘法表 h = lambda x, y : x*y for a in range(1,10) : for b in range(1,10) : print("{0:4}x{1:1}={2:2}".format(a,b,h(a,b)),end="") print() 72 lambda 函式

enumerate 函式 : 列舉函式 enumerate(a): 將序列的下標與數值打包 >>> d = enumerate( ["a","b","c"] ) a b c (0, a ) (1, b ) (2, c ) for i, v in d : 或 print( i, :, v ) 0 : a 1 : b 2 : c for m in d : print(m[0], :,m[1]) 73 zip 函式

zip 函式 ( 一 ) : 拉鏈函式 zip(a,b,c...): 將多個一維序列合成多維序列 >>> a = list( zip( [1,2,3], ["a","b","c"] ) ) >>> a [(1, a ), (2, b ), (3, c )] A : B : 1 2 3 a b c 1 a 2 b 3 c for x, y, z in zip( [1,2], ["a","b"], (5,"c")) : print(x,y,z) 1 a 5 2 b c 74 zip 函式

zip 函式 ( 二 ) : 拉鏈函式 zip(* 多維串列 ): 將多維序列拆解為多個一維序列 >>> [a,b] = zip( *[(1, a ),(2, b ),(3, c )] ) >>> a [1, 2, 3] >>> b [9, 8, 7] 星號置於串列前效果有如拆解串列成為一個個元素 zip( *[(1,2),(3,4)] ) zip( (1,2),(3,4) ) 1 a 2 b 3 c 1 2 3 a b c a b 75 zip 函式

map 函式 ( 一 ) : 映射函式 map(fn,seq): 取出 seq 序列的元素送到 fn 函式處理 >>> a = list(map( len, [ "cat", "tiger", "lion" ] )) >>> a [3, 5, 4] "cat" "tiger" "lion" len 3 5 4 >>> sum( map( int, [ "3", "5", "7" ] ) ) 15 NOTE: map 也可同時處理多個 seq 序列 76 map 函式

map 函式 ( 二 ) : 映射函式 map 常與 for 迴圈合用 : # 計算輸入數字的平方和 : sum = 0 for n in map( int, input("> ").split(" ") ) : sum += n*n print( sum ) > 2 3 1 14 77 map 函式

map 函式 ( 三 ) : 映射函式 map 與 lambda 函式合用 : # 單一串列 : 攝式轉華式 for x, y in map( lambda c : ( c, 9*c/5 + 32 ), range(0,101,10) ) ) : print( "{0:3} --> {1:3.0f}".format(x,y) ) 0 --> 32 10 --> 50... 100 --> 212 # 多個串列 : 數字與字串合併 for x in map( lambda x, y : x+str(y),["a","b","c"],[4,5,6] ) ) ) print(x,end=" ") a4 b5 c6 78 map 函式

filter 函式 : 過濾函式 filter(fn,seq): 濾出 seq 序列滿足 fn 函式條件的元素 # 印出 5 的倍數 for a in filter( lambda x : x%5==0, range(1,51) ) : print("{0} ".format(a),end="") 5 10 15 20 25 30 35 40 45 50 # 印出大於 0 的數 for a in filter( lambda x : x > 0, [1,3,-1,2,9] ) : print("{0} ".format(a),end="") 1 3 2 9 79 filter 函式

reduce 函式 ( 一 ) reduce(fn,seq): 兩兩前後接續取出 seq 序列元素於 fn 函式內運算 1 2 3 4 5 10 3 6 10 # 計算 1 加到 10 的和 print( reduce( lambda x,y : x+y, range(11)) ) 55 NOTE: reduce 須使用 import functools 80 reduce 函式

reduce 函式 ( 二 ) # 在字母間加入橫線 print( reduce( lambda x,y : x+ - +y, " 數學系 " ) ) 數 - 學 - 系 # C 42 取 6 數量 print( reduce( lambda x,y : x*y, range(7,43) ) /reduce( lambda x,y : x*y, range(1,37) ) ) 5245786 81 reduce 函式

sort 函式 ( 一 ) 排序函式 : A.sort(): 將 A 序列由小排到大 sorted(a): 回傳 A 序列由小排到大的結果, 但 A 序列不變 >>> a = [ 12, 76, 3 ] >>> sorted(a) [3, 12, 76] >>> a [12, 76, 3] >>> a.sort() >>> a [3, 12, 76] NOTE: tuple 僅能使用 sorted 排序 82 sort 函式

sort 函式 ( 二 ) 逆向排序 : A.sort(reverse=True) sorted(a,reverse=true) >>> a = [ 12, 76, 3 ] >>> a.sort(a,reverse=true) >>> a [76, 12, 3] >>> b = [ "cat", "ox", "tiger" ] >>> sorted( map(len,b), reverse=true ) [5, 3, 2] 83 sort 函式

sort 函式 ( 三 ) 自訂 lambda 函式排序 : A.sort(key=fn) sorted(a,key=fn) # 比較個位數字, 由小排到大 >>> sorted( [12,76,3], key=lambda x : x%10 ) [12, 3, 76] # 比較字串長度, 由大排到小 >>> sorted( ["cat","ox","tiger"], key=len,reverse=true) [ tiger, cat, ox ] 84 sort 函式

sort 函式 ( 四 ) 自訂函式排序方式 : # 比較日期 : 先年後月, 由小到大 def by_date1 (x) : s = x.split( / ) return ( int(s[1]), int(s[0]) ) # 比較日期 : 先月後年, 由小到大 def by_date2 (x) : s = x.split( / ) return ( int(s[0]), int(s[1]) ) a = [ 2/2010, 9/2010, 7/2009, 7/2008 ] print( sorted(a,key=by_date1) ) [ 7/2008, 7/2009, 2/2010, 9/2010 ] print( sorted(a,key=by_date2,reverse=true) ) [ 9/2010, 7/2009, 7/2008, 2/2010 ] 85 sort 函式

檔案處理 : 讀檔 ( 一 ) 檔案處理物件 : 負責處理讀 / 存檔的物件 設定讀檔物件 : # infile : 讀檔物件,fname: 檔名,r: 讀檔 infile = open("fname","r") # 由 infile 每次讀入一行存在 line for line in infile : # 去除每行後的空白字元後印出 print(line.strip()) # 關檔 infile.close() NOTE: (1) 關檔後,infile 可以再用來開啟其它的檔案 (2) open("fname","r") 也可寫為 open("fname") (3) 檔案資料讀取會一字不漏的讀取, 不會處理換行字元 86 檔案處理

檔案處理 : 讀檔 ( 二 ) 使用 with... as... # infile 物件負責將資料由 fname 檔讀入 with open("fname","r") as infile : # 由 infile 每次讀入一整行 for line in infile : # 讀入由逗點隔開的資料行 a = line.strip().split(",") print(" ".join(a)) NOTE: 在離開 with... as 後, 檔案會自動關閉 87 檔案處理

檔案處理 : 讀檔 ( 三 ) readline(): 一次讀取一行資料後回傳 readlines(): 讀取檔案剩下的資料轉成串列後回傳 read(n): 讀取 n 個位元組資料後回傳 read(): 將檔案剩下的資料串成一個字串後回傳 with open("aa","r") as infile : NOTE: # 讀取第一行並印出 print( infile.readline().rstrip() ) # 讀取第二行起的所有資料存入 lines 串列 lines = infile.readlines() for line in lines : # 印出每行的前 12 個字元 print(line[0:12]) (1) lines = infile.readlines() 也可寫成 lines =list(infile) (2) 當讀到檔案末尾時,readline() 回傳空字串 ("") 88 檔案處理

檔案處理 : 存檔 ( 一 ) 設定存檔物件 : # outfile : 存檔物件,fname: 檔名,w: 存檔 outfile = open("fname","w") # 儲存九九乘法表 : for i in range(1,10) : line = "" for j in range(1,10) : s = "{0:3} x {1:1} = {2:2}".format(i,j,i*j) line += s # 儲存一行, 後加上換行字元 outfile.write(line+"\n") # 關檔 outfile.close() NOTE: (1) 關檔後,outfile 可以再用來開啟其它的檔案 (2) write() 僅能存入字串 (3) 若將 w 改為 "a" 則表示輸出的資料將由檔案的末尾處寫入 89 檔案處理

檔案處理 : 存檔 ( 二 ) 使用 with... as # 同時開啟 aa 檔讀入資料與 bb 檔儲存資料 with open("aa","r") as infile, open("bb","w") as outfile : c = 1 for line in infile : # 讀入資料後加上行數輸出 out = "[{0:0>2}] {1}\n".format(c,line.strip()) outfile.write(out) c += 1 NOTE: (1) with... as 可以同時開啟數個檔案 (2) 在離開 with... as 後, 檔案會自動關閉 90 檔案處理

檔案處理 : 存檔 ( 三 ) writelines(a): 將序列字串 A 合併存入檔案 with open("aa","w") as f : # 印出 0 到 9 存到檔案 "aa", 每個數字一行 f.writelines( "{0}\n".format(n) for n in range(10)) # 也可使用 f.writelines( map( lambda n : str(n)+"\n",range(10) ) ) # 也可使用 for x in range(10) : f.write( str(x)+"\n" ) # 也可使用, 但末尾少了一個換行字元 f.write( "\n".join( map(str,range(10) ) ) ) 91 檔案處理

字典型別設定 ( 一 ) dictionary: 可使用非整數下標的串列 字典物件的設定 >>> # 定義 a 為空字典 >>> a = {} >>> # 可使用字串當下標 >>> a["one"] = 1 >>> a["two"] = 2 >>> a { two : 2, one : 1} >>> # 也可使用數字當下標 >>> b = { 1 : one } >>> b[2] = "two" >>> b[1.1] = "one point one" >>> b {1: one, 2: two, 1.1: one point one } NOTE: 字典物件使用前須先設定 92 dictionary 型別

字典型別設定 ( 二 ) 使用 dict comprehensions: >>> a = { x : x*x for x in range(1,5) } >>> a {1: 1, 2: 4, 3: 9, 4: 16} >>> # 對調 a 的 key 與 value 成為 b 字典 >>> b = { v : k for k, v in a.items() } 使用 dict 設定 : >>> # 此種設定方式的下標須為字串 >>> a = dict( one = 1, two = 2, three = 3 ) >>> a { three : 3, two : 2, one : 1} 使用 zip: >>> c = dict( zip( ("one","two"), (1,2) ) ) >>> c { two : 2, one : 1} 93 dictionary 型別

字典資料取用 如果 a = { "one" : 1, "two" : 2 } keys(): 取出所有的下標 ( 取出次序不定 ) for k in a.keys() : print( k, a[k] ) 輸出 : two 2 one 1 NOTE: a.keys() 也可使用 list(a) values(): 取出資料值 ( 取出次序不定 ) for v in sorted(a.values()) : # 對取出的值排序 print( v, end=" " ) 輸出 :1 2 items(): 取出成對的下標與資料值 ( 取出次序不定 ) for k, v in a.items() : print( k, v ) 輸出 : one 1 two 2 94 dictionary 型別

字典基本操作 ( 一 ) len(a): 回傳字典物件 A 儲存的筆數 >>> a = { "one" : 1, "three" : 3 } >>> len(a) 2 del(a[key]): 去儲字典 A 下標為 key 的資料 >>> del( a["one"] ) >>> a { three : 3} A.update(B): 將字典物件 B 內容加入 A >>> c = { "three" : 3, "four" : 4 } >>> a.update(c) >>> c { four : 4, three : 3, one : 1} 95 dictionary 型別

字典基本操作 ( 二 ) a in A: 判斷下標 a 是否在字典物件 A 內 >>> c = "three" : 3, "four" : 4 >>> "four" in c True >>> "five" in c False A.get(a,b=None): 找出在字典物件 A 內下標為 a 的值, 若 下標 a 不存在, 則回傳 b 值 >>> c.get("three") >>> 3 >>> c.get("three",5) >>> 3 >>> c.get("six") >>> c.get("six",6) >>> 6 96 dictionary 型別

複製字典物件 A.copy(): 複製 A 字典物件內容, 計憶空間相依 copy.deepcopy(a): 複製出記憶空間獨立的 A 物件內容 >>> c = [ 4, iv ] >>> d = { "one" : 1, "four" : c } >>> e = d.copy() >>> f = copy.deepcopy(d) >>> e { four : [4, iv ], one : 1} >>> del( c[1] ) >> e { four : [4], one : 1} >> f { four : [4, iv ], one : 1} NOTE: (1) 使用 copy.deepcopy(a) 型式, 須加入 import copy (2) deepcopy 也可用來複製有獨立計憶空間的序列物件 97 dictionary 型別

字典與串列互換 字典轉串列 : >>> a = { "one" : 1, "two" : 2 } >>> vals = list( a.values() ) >>> keys = list( a.keys() ) >>> items = list( a.items() ) >>> keys [2, 1] >>> items [( two, 2), ( one, 1)] 串列轉字典 : >>> b = [ ( "one", 1 ), [ "two", 2 ] ] >>> c = dict(b) >>> c { two : 2, one : 1} 98 dictionary 型別

字典範例 ( 一 ) : 單字數量 a = 一紙公文九個該, 一該該出是非來 從此該員該注意, 不該該處不該該 c = {} for x in a : c[x] = c.get(x,0) + 1 # 列印所有的資料 i = 0 for k in c.keys() : if ( k ==, or k == ) : continue i+=1 print(k,c[k],end= if i%5 else \n ) print() # 依照數值大小排序 i = 0 for k, v in sorted( c.items(), key= lambda x : x[1], reverse=true) : if ( k ==, or k == ) : continue i += 1 print(k,v,end= if i%5 else \n ) 員 1 一 2 此 1 文 1 來 1 從 1 個 1 不 2 公 1 是 1 該 9 處 1 意 1 注 1 紙 1 出 1 九 1 非 1 該 9 一 2 不 2 員此 1 文 1 來 1 從 1 個 1 公 1 是 1 處 1 意 1 注 1 紙 1 出 1 九 1 非 1 99 dictionary 型別

字典範例 ( 二 ) : 稀疏矩陣 # 使用二維下標當 key: from random import * x = list(range(81)) shuffle(x) # 設定 mat = { (0,1):2 } for c in range(10) : if ( x[c] == 1 ) : continue i = x[c]//9 j = x[c]%9 mat[(i,j)] = randint(1,9) # 依序列印 n = 0 for i, j in sorted(mat) : n += 1 print( (,i,,,j, ) =, mat[(i,j)], \ end= if n%4 else \n ) ( 0, 1 ) = 2 ( 1, 0 ) = 3 ( 1, 4 ) = 2 ( 2, 0 ) = 9 ( 5, 0 ) = 1 ( 5, 5 ) = 3 ( 5, 7 ) = 9 ( 6, 8 ) = 1 ( 7, 7 ) = 7 ( 8, 1 ) = 5 ( 8, 5 ) = 6 100 dictionary 型別

set : 集合 集合 : 由不同元素所組成 集合設定 : >>> a = { 3, 2, 2} >>> a 2, 3 >>> b = set( [1,2,2,3] ) >>> b {1, 2, 3} 空集合 >>> x = set() >>> # 使用 clear() 取得空集合 >>> y = set([1,2]) >>> y.clear() 複製集合 >>> x = set([1,2]) >>> y = x.copy() 101 set 型別

set : 增減集合元素 add(a): 加入 a 元素 >>> b = set() >>> b.add(3) >>> b 3 remove(a): 刪除 a 元素 但集合若無此元素, 產生錯誤訊息 >>> b = set( [1,2,3] ) >>> b.remove(2) >>> b {1, 3} discard(a): 若集合有 a 元素則刪除, 否則沒動作 >>> b = set( [1,2,3] ) >>> b.discard(2) >>> b {1, 3} clear(): 清空集合 >>> b = set( (1,2) ) >>> b.clear() >>> b set() 102 set 型別

set : 是否為集合元素 a in A : 檢查 A 集合是否有 a 元素 >>> b = set( [1,2] ) >>> 2 in b True >>> 3 in b False a not in A : 檢查 A 集合是否沒有 a 元素 >>> b = set( [1,2] ) >>> 2 not in b False len(a) : A 集合的元素個數 >>> b = set( [1,5,2] ) >>> len(b) 3 103 set 型別

set : 聯集, 交集, 差集, 對稱差集 ( 一 ) a = { 2, 3, 4 }, b = { 5, 3, 6 } : 聯集 >>> a b {2, 3, 4, 5, 6} & : 交集 >>> a & b {3} - : 差集 >>> a - b { 2, 4} >>> b - a { 5, 6} ^ : 對稱差集 >>> a ^ b { 2, 4, 5, 6 } 104 set 型別

set : 聯集, 交集, 差集, 對稱差集 ( 二 ) a = { 2, 3, 4 }, b = { 5, 3, 6 } c = { 3 } =: 聯集更新 >>> a = b >>> a {2, 3, 4, 5, 6} &=: 交集更新 >>> a &= b >>> a { 3 } =: 差集更新 >>> a -= b >>> a {2, 4} ^=: 對稱差集更新 >>> a ^= b >>> a {2, 4, 5, 6} 105 set 型別

set : 包含 a = { 2, 3, 4 }, b = { 5, 3, 6 }, c = { 3 } A >= B: A 集合是否包含 B 集合 A > B: A 集合是否包含 B 集合, 但 A 不等於 B A <= B: A 集合是否包含於 B 集合 A < B: A 集合是否包含於 B 集合, 但 A 不等於 B A == B: A 集合是否等於 B 集合 A!= B: A 集合是否不等於 B 集合 >>> a >= c True >>> a <= b False >>> b == c False A.isdisjoint(B): A B 兩集合是否無交集 >>> a.isdisjoint(b) False 106 set 型別

frozenset : 凍集合 frozenset: 集合建構後就不能被更動 >>> a = frozenset([1,2]) >>> a frozenset({1, 2}) >>> a.add(3) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: frozenset object has no attribute add frozenset 可成為其它集合的元素 >>> a = frozenset([1,2]) >>> b = set({3,a}) >>> b {frozenset({1, 2}), 3} 107 frozenset 型別

strings 與 bytes strings 與 bytes 為同筆資料儲存的不同型式 : strings bytes 型別 str bytes, bytearray 儲存內容 unicode text encoded unicode data 序列 character 介於 [0,255] 間的位元組 型式 cat 中 b cat b \xe4\xb8\xad str 轉 bytes x = 中 y = x.encode() x = 中 y = bytes(x, utf-8 ) y = bytearray(x, utf-8 ) bytes 轉 str x = y.decode() y= b \xe4\xb8\xad x = str(y, utf-8 ) y = b \xe4\xb8\xad NOTE: bytearray 為 bytes 的 mutable 版本型別 108 strings 與 bytes

bytes 與 bytearray 操作 可使用下標取得資料 : >>> x = "cat" >>> y = x.encode() >>> for i in range(len(x)) : print(x[i],y[i], end="-") c 99-d 97-t 116 可當成序列使用 : >>> y = bytearray( cat, utf-8 ) >>> for c in y : print(c,end=" ") 99 97 116 可使用 list 轉為數字串列 >>> list("abc".encode()) [97, 98, 99] 截取資料 : >>> y = " 中央 ".encode() >>> y[3:6] b \xe5\xa4\xae >>> y[3:6].decode() 央 >>> z = bytearray(" 中央 ", utf-8 ) >>> z[3:6] = " 大 ".encode() >>> z.decode() 中大 NOTE: bytes 為 immutable, 無法更動資料 109 bytes 與 bytearray

二進位檔案的儲存 二進位檔 : 檔案內容是以二進位方式儲存 存檔模式 : "wb" import struct with open("fname","wb") as outfile : # 字串可直接轉成 bytes 後寫入檔案 outfile.write(bytes(" 中央大學 ", utf-8 )) outfile.write("math DEPT".encode()) # 將兩個整數 n, n*n 與一個浮點數 n/10 打包成 # 2 個 int 與 1 個 double for n in range(10) : outfile.write(struct.pack("2id",n,n*n,n/10)) pack 打包參數 參數 C/C++ 型別 python 型別佔用位元組數 c char string of length 1 1 i int int 4 d double float 8 NOTE: 使用 pack 需要使用 struct package 110 二進位檔案

二進位檔案的讀檔 讀檔模式 : "rb" with open("fname","rb") as infile : # 中央大學 共佔 12 位元組 ncu = infile.read(12).decode() # 讀入 MATH DEPT math = infile.read(9).decode() print(ncu,math) for n in range(10) : # 讀取 16 個位元組資料, 拆解成 2 個 int # 與 1 個 double 存入 num tuple 內 num = unpack("2id",infile.read(16)) # 列印以上 3 個數字 print(" ".join(map(str,num))) NOTE: 使用 unpack 需要使用 struct package 111 二進位檔案

序列型別 :sequence 序列型別 : 資料如同串成一列的有次序排列 六種基本型別 : strings,byte sequence,byte arrays,lists,tuples,range objects 皆由更小的元素組成 : 序列型別樣式元素型別 str "cat" character (string of one element) bytes b"cat" int in [0,255] bytearray bytearray(b cat ) int in [0,255] list [ 2, "cat", [ 3, 2.5 ] ] any data type tuple ( "cat", ( 2+3j, 4 ) ) any data type range range(10) int 112 序列型別

序列型別 : 常用操作 ( 一 ) 整數下標取得資料 序列型別 x x[1] str "cat" a bytes b"cat" 97 bytearray bytearray(b cat ) 97 list [ 2, "cat", [ 3, 2.5 ] ] "cat" tuple ( "cat", ( 2+3j, 4 ) ) ( (2+3j), 4 ) range range(10) 1 下標截取 : 序列型別 x x[1:3] str "cat" at bytes b"cat" b at bytearray bytearray(b cat ) bytearray(b at ) list [ 2, "cat", [ 3, 2.5 ] ] [ "cat", [ 3, 2.5 ] ] tuple ( "cat", ( 2+3j, 4 ), 5 ) ( ( (2+3j), 4 ),5 ) range range(2,10,3) range(5,11,3) 113 序列型別

序列型別 : 常用操作 ( 二 ) S 為序列, x 為元素, n 為整數 len(s): 序列長度 max(s), min(s): 序列的最大值與最小值 ( 所有元素須相同型別 ) x in S, x not in S: 檢查 x 是否在 S 序列內 S.count(x): 回傳 x 元素在 S 序列出現的次數 S.index(x): 回傳 x 元素在 S 序列中第一次出現的下標 +, += 合成 : 序列合成, 對 immutable 序列無法使用 += >>> "ncu" + "math" ncumath x * n, n * x : 淺層複製元素 >>> 3 * "cat" catcatcat NOTE: range 物件無法使用最後兩種用法 114 序列型別

函式 函式語法 : def fname( arg1, arg2,... ) : body 函式範例 : def factorial(n) : # documentment string or docstring """ 計算 n 階乘 """ p = 1 for s in range(2,n+1) : p *= s return p (1)docstring: 以上三個雙 ( 單 ) 引號夾住的字串 ( 可跨行 ) 為函式 factorial 的說明文字, 可以使用 factorial.doc 印出來 (2) 使用 return arg 停止並離開函式, 回傳 arg 值 (3) 若無 return 則回傳 None 115 函式

函式參數設定 ( 一 ) 參數位置對應 : 依參數次序一一對應 def power( a = 10, n = 1 ) : p = a for s in range(2,n) : p *= a return p 函式參數設定計算結果說明 power(3,2) 9 a = 3, n = 2 power(3) 3 使用 a = 3, n = 1 power() 10 使用 a = 10, n = 1 預設值的設定方式, 由末尾逆向排列 # 錯誤的預設值設定 def power( a = 10, n ) : body 116 函式

函式參數設定 ( 二 ) 參數名稱對應 : 直接使用參數名稱傳遞數值 def age( byear, year = 2014 ) : return year byear 函式參數設定 計算結果說明 age(byear=2000) 14 byear = 2000, year = 2014 age(year=2015,byear=2002) 13 byear = 2002, year = 2015 age(year=2015) 錯誤 byear 不知 NOTE: 若以名稱對應方式傳入參數數值, 則參數的次序無影響 117 函式

函式 : 星號式子語法 星號式子語法 : >>> ( a, *b ) = ( 1, 2, 3, 4 ) >>> a 1 >>> b [2, 3, 4] >>> a, b (1, [2, 3, 4]) >>> *a, b, c = [ 1, 2, 3, 4 ] >>> a, b, c ([1, 2], 3, 4) NOTE:(1) 一個設定式子不可超過一個以上的星號 (2) 在指定式時, 星號語法僅能用來被設定 ( 指定左側 ) 118 函式

函式 : 不定數量的位置參數 使用星號式子語法 : def sum( n, *args ) : s = n for m in args : s += m return s 函式設定方式計算結果說明 sum() 錯誤 n 無設定 sum(2) 2 args = () sum(2,1,3) sum(2,1,3,8) 6 args=(1,3) 14 args=(1,3,8) 119 函式

函式 : 不定數量的關鍵字參數 將過多參數存入以 ** 表示的字典物件內 : def record( a, **b ) : print(a, " :") for k, v in b.items() : print(k,":",v) 函式設定方式輸出說明 record("tom") Tom : b 空字典 record("tom",age=20) Tom : age:20 record("tom",age=20,gender=male) Tom : age:20 gender: male 120 函式

函式 : 混合不定數量的位置與關鍵字參數 位置參數與關鍵字參數可以混合使用 : def record( a, *b, **c ) : print(a, " :", b) for k, v in c.items() : print(k,":",v) 函式設定方式輸出說明 record("tom") Tom : b (), c {} record("tom",183,50) Tom : (183, 50) c {} record("tom",age=20,gender=male) Tom : () age:20 gender:male record("tom",183,age=20,gender=male) Tom : (183) age:20 gender:male b () NOTE: 不定數量的混合型態參數較易出錯須仔細處理 121 函式

函式 : 傳入串列到個別參數 若要將串列傳入函式的個別獨立參數, 可用 * 號拆解 (unpack) 串列後對應到函式的個別參數 def sum( a, b ) : return a + b >>> sum(1,4) 5 >>> c = [1,4] >>> sum(*c) # a, b = c[0], c[1] 4 >>> sum(c) # 錯誤,sum 需要兩個參數 # 但僅輸入一個參數 122 函式

函式 : 傳入字典到個別參數 若要將字典傳入函式的個別參數, 可用 ** 符號拆解 (unpack) 字典物件對應到函式的個別參數 def sum( math, phy ) : return math + 2*phy >>> sum(1,4) 9 >>> c = { phy :1, math :4 } >>> sum(**c) # math, phy = 4, 1 6 >>> sum(c) # 錯誤,sum 需要兩個參數 # 但僅輸入一個參數 123 函式

函式 : 變更參數值 immutable 物件參數內容無法在函式內被更動, mutable 物件參數內容可在函式內被更改 def fn( n, s, a, b, c ) : # n 為整數, s 為字串, 其餘參數為串列 n += 1 s += "dog" a.append("dog") b = [ "dog" ] c[0] = "dog" print(n,s,a,b,c) >>> x=5 ; y=cat ; z=[1] ; d=[ cat, cat ] ; e=[ cat ] >>> print(x,y,z,d,e) 5 cat [1] [ cat, cat ] [ cat ] >>> fn(x,y,z,d,e) 6 catdog [1, dog ] [ dog ] [ dog ] >>> print(x,y,z,d,e) 5 cat [1, dog ] [ cat, cat ] [ dog ] NOTE: 函式內 a 與 c 運算是用來改變串列資料值, b 則是指向新的串列 124 函式

函式 : 局部, 全域變數 局部變數 (local variable): 函式內使用的介面參數與其內使用的變數名稱, 僅在內部使用, 不會向外影響 def fn1( a ) : # a 與 b 皆為函式的局部變數 a += 3 b = 1 print(a,b) >>> a = 2 >>> fn1(a) 5 >>> a 2 全域變數 (global variable): 不透過參數傳入, 直接使用函式外部的變數 def fn2() : # 函式直接使用外部的 a 變數 global a a += 3 print(a) >>> a = 2 >>> fn2(a) 5 >>> a 5 125 函式

可迭代器與迭代器 :iterable 與 iterator( 一 ) iterable( 可迭代器 ): 可用來迭代的物件, 例如 : 用在 for 或 while 迴圈, 或其它需要迭代的函式 for x in [1,4,9] : print(x) for x in "cat" : print(x) for x in range(10) : print(x) with open("fname","r") as infile : for line in infile : print(line) map( str, [1,4,9] ) 以上的串列 ([1,4,9]), 字串 ("cat"), range(10), infile 都是 iterable 使用 iter () 用來產生迭代器 (iterator) >>> itr1 = [1,4,9]. iter () >>> itr2 = iter([1,4,9]) # 也寫成左邊的型式 126 可迭代器與迭代器

可迭代器與迭代器 :iterable 與 iterator( 二 ) iterator( 迭代器 ): 物件定義如何迭代, 利用 next () 函式取得下一筆資料 >>> itr = [1,4,9] >>> itr. next () # 第一筆資料 1 >>> # next 為 next () 的簡化型式 >>> next(itr) 第二筆資料 4 當全部的資料取完後, 回傳 StopIteration 信號 >>> next(itr) 第三筆資料 9 >>> next(itr) 沒有資料了 Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration 不見得迭代器都需要回傳 StopIteration 信號 127 可迭代器與迭代器

可迭代器與迭代器 :iterable 與 iterator( 三 ) iterable 如同可用 迭代 方式取出的資料庫, iterator 為知道如何由 iterable 資料庫取出下筆資料的幫手 iterable 利用 iter 產生 iterator 幫手, iterator 使用 next 取出在 iterable 內的資料 a iit 1 4 9 iterable itr=iter(a) itr iterator ii next(itr) 1 next(itr) 4 next(itr) 9 next(itr) StopIteration data source helper 128 可迭代器與迭代器

可迭代器與迭代器 :iterable 與 iterator( 四 ) 迴圈運作機置 : alist = [1,4,9] for x in alist : print(x) for 是為可迭代的迴圈, in 之後須要迭代器幫手來將 alist 的資料依次取出 執行 alist. iter () 或 iter(alist) 產生迭代器幫手 itr( 暫時命名 ), 因此 alist 為可迭代器 進入 for 迭代過程中, 重複執行 itr. next () 或 next(itr) 取得下筆資料, 每筆資料名稱為 x 當 alist 所有資料取完後, next(itr) 送出 StopIteration 信號代表終結, 迴圈結束 129 可迭代器與迭代器

產生器函式 :generator function( 一 ) generator function: 函式用來產生一種特殊型式的迭代器 generator 使用 yield 送出運算過程中的資料, 資料送出後函式仍繼續執行 # 產生初值 a, 比值 r 的前 n 項等比數列 def gparray( a, r, n ) : for i in range(n) : yield a a *= r for x in gparray(3,2,10) : print(x,end=" ") 輸出 :3 6 12 24 48 96 192 384 768 1536 print( "->".join( map( str, gparray(2,3,5) ) ) ) 輸出 :2->6->18->54->162 NOTE:generator function 使用 yeild 送出運算過程中的資料, 函式仍繼續執行 但一般函式在使用 return 將其後的資料回傳後, 函式隨即中止 130 產生器

產生器函式 :generator function( 二 ) 使用 list(gen) 將產生器的所有資料轉成串列 a = list( gparray(2,3,5) ) print(a) 輸出 :[2, 6, 18, 54, 162] generator: 為迭代器, 可使用 next () 或 next(gen) 取得由 yield 回傳的資料 # 產生初值 a, 比值 r 的數列 def gparray( a, r ) : p = a while True : yield p p *= r itr = gparray(1,2) for i in range(5) : print(next(itr),end=" ") 輸出 :1 2 4 8 16 # 取出輸入產生器的前 n 個數值 def frontn( fn, n ) : for i in range(n) : yield next(fn) print( "->".join(map(str, frontn(gparray(1,2),8) ) ) ) 輸出 :1->2->4->8->16->32->64->128 131 產生器

第一類物件 :first-class object python 的函式屬於第一類物件, 有以下特性 : 可以被將函式當成參數傳入另一個函式中 def sq( f ) : return f(x)**2 可以在另一個函式中回傳出函式 可將函式設定於其它變數中 def sum( f, g ) : def fn(x) : return f(x)+g(x) return fn h = sum(sin,cos) print(h(0.1)) 可以存入資料結構中 fn = [ sin, cos, exp ] for x in range(10) : x /= 10 for f in fn : print(f(x),end=" ") print() NOTE: 同樣的, 所有的 python 的物件都屬於第一類物件 132 第一類物件

函式裝飾器 :function decorator decorator: 用來包裝函式的函式, 可用來擴增原有函式的功能 def decorate( fn ) : def wrapper(a,b,dx) : vals = [] x = a while x < b : vals.append(fn(x)) x += dx return vals return wrapper 以上 decorate 函式將輸入的函式 fn 包裹在其內的 wrapper 函式內,decorate 函式執行完後回傳 wrapper 包裹函式 wrapper 包裹函式的輸入參數為 (a,b,dx), 回傳 fn(x) 在 x 介於 [a,b), 等差數為 dx 之間的函數值, 以串列方式輸出 NOTE:decorate 與 wrapper 非程式保留字 133 函式裝飾器

函式裝飾器 : 使用方式 ( 一 ) decorate 函式回傳其內的 wrapper 函式, 若讓 g = decorate( abs ) # g 函式即為 : def g(a,b,dx) : vals = [] x = a while x < b : vals.append( abs(x) ) x += dx return vals # 因此 : print( g(-3,4,1) ) 輸出 :[3, 2, 1, 0, 1, 2, 3] 134 函式裝飾器

函式裝飾器 : 使用方式 ( 二 ) 使用方式 : # 平方函式 : def sq(x) : return x * x # 立方函式 : def cubic(x) : return x * x * x # 將 decorate 內部的 wrapper 函式傳出當成 sq series 函式 sq series = decorate(sq) # sq series 的參數列與 wrapper 包裹函式一樣 print( sq series(0,5,1) ) 輸出 :[0, 1, 4, 9, 16] # 將 decorate 內部的 wrapper 函式傳出當成 cubic series 函式 cubic series = decorate(cubic) # cubic series 的參數列與 wrapper 包裹函式一樣 print( cubic series(0,5,1) ) 輸出 :[0, 1, 8, 27, 64] 135 函式裝飾器

函式裝飾器 : 使用方式 ( 三 ) 可以直接取代舊函式 : def cubic(x) : return x * x * x # 包裹函式使用舊名稱, 等同擴大原始的函式功能 cubic = decorate(cubic) # 以下的 cubic 為包裹後的新函式, 需要 3 個參數 print( cubic(0,5,1) ) 輸出 :[0, 1, 8, 27, 64] 上面程式碼的前兩行可簡寫為 : @decorate def cubic(x) : return x * x * x print( cubic(0,5,1) ) 輸出 :[0, 1, 8, 27, 64] 136 函式裝飾器

函式裝飾器 : 範例 # 列印不等數量的函式值 : def decorate( fn ) : def wrapper(a,b,dx,*arg) : print( {0:>8} ".format("x"),end=" ") for i in range(len(arg)) : name = arg[i]. name + "(" + fn. name + "(x))" print("{0:>14}".format(name),end=" ") print() x = a while x < b+0.1*dx : print("{0:>10.2f}".format(x),end=" ") for i in range(len(arg)) : print( "{0:>14.2f}".format(arg[i](fn(x))), end = " " ) print() x += dx return wrapper @decorate def twox(x) : return 2 * x @decorate def fourx(x) : return 4 * x NOTE: 程式執行中 foo 函式的名稱可使用 foo. name 取得 137 函式裝飾器

函式裝飾器 : 執行結果 twox(0,0.5,0.1,sin,cos) x sin(twox(x)) cos(twox(x)) 0.00 0.00 1.00 0.10 0.20 0.98 0.20 0.39 0.92 0.30 0.56 0.83 0.40 0.72 0.70 0.50 0.84 0.54 fourx(0,0.5,0.1,sin) x sin(fourx(x)) 0.00 0.00 0.10 0.39 0.20 0.72 0.30 0.93 0.40 1.00 0.50 0.91 138 函式裝飾器