# a.資料科學 - Python 速成班(進階)
###### tags: `Data Sicnce From Scratch`
> <font color="#EA0000" >**#IPython有個奇妙的功能 %paste,它可以正確貼上任何你放在剪貼簿中的程式碼**</font>
## 1.函式 (Function)
* <font color="#0080FF">**頭等(First-class)函式**</font>
```python=+
#Python 的函式屬於一等(First-class)函式,也就是說,我們可以把函式指定給某個變數,然後把它傳進某個函式中
def double(x):
return x * 2
def apply_to_one(f):
"""給予傳進來的函式「1」的參數"""
return f(1)
my_double = double
result = apply_to_one(my_double)
print(result)
```
> ```2```
##
* <font color="#0080FF">**短匿名函式(或lambda函式)**</font>
```python=+
y = apply_to_one(lambda x:x+4)
print(y)
```
> ```5```
##
* <font color="#0080FF">**把lambda指定給變數,不推薦**</font>
```python=+
another_double = lambda x:x*2
print(another_double(2))
def another_double(x):
"""建議改用這種作法"""
return x*2
print(another_double(2))
```
> ```4```</br>
> ```4```
##
* <font color="#0080FF">**指定函式內參數名稱**</font>
```python=+
def full_name(first = "What's-his-name",last = "Something"):
return first + " " + last
full_name("Joel","Grus")
full_name("Joel")
full_name(last = "Grus")
```
> ```What's-his-name Grus```
## 2.字串 (String)
* <font color="#0080FF">**跳脫字元**</font>
```python=+
tab_string = "\t"
print(tab_string,len(tab_string))
```
> ``` 1```
##
* <font color="#0080FF">**建立原始字串**</font>
```python=+
r_tab_string = r"\t" #用「r」建立raw(原始)-string
print(r_tab_string,len(r_tab_string))
```
> ```\t 2```
## 3.例外處理 (Exception)
* <font color="#0080FF">**簡單的例外處理結構**</font>
```python=+
try:
print(0 / 0)
except ZeroDivisionError:
print("cannot divide by zero!!")
else:
print("unexpected error!!")
finally:
print(">>process end")
```
> ```cannot divide by zero!!```</br>
> ```>>process end```
## 4.列表 (List)
* <font color="#0080FF">**列表的新增**</font>
```python=+
x = [1,2,3]
x.extend([4,5,6]) #會更改列表本身
print(x)
x = [1,2,3]
y = x + [4,5,6] #如不想更改列表本身可用「+」
y
```
> ```[1, 2, 3, 4, 5, 6]```</br>
> ```[1, 2, 3, 4, 5, 6]```
## 5.元組 (Tuple)
> <font color="#EA0000">**#例外處理(Exception):</br>#修改元組內容 - TypeError**</font>
* <font color="#0080FF">**例外處理**</font>
```python=+
my_list = [1,2]
my_tuple = (1,2)
other_tuple = 3,4
my_list[1] = 3
try:
my_tuple[1] = 3
except TypeError:
print("cannot modify tuple's content!")
```
> ```cannot modify tuple's content!```
##
* <font color="#0080FF">**函式回傳多個值**</font>
```python=+
def sum_and_product(x,y):
return (x+y),(x*y) #依舊是回傳一個值,因為統一被打包成一個Tuple
sp = sum_and_product(2,3)
s,p = sum_and_product(5,10)
print("sp =",sp)
print("s =",s,"p =",p)
```
> ```sp = (5, 6)```</br>
> ```s = 15 p = 50```
##
* <font color="#0080FF">**多重賦值**</font>
```python=+
#元組和列表都可使用多重賦值(multiple assignment)
x,y = 1,2
x,y = y,x
print("x =",x)
print("y =",y)
```
> ```sp = (5, 6)```</br>
> ```s = 15 p = 50```
## 6.字典 (Dict)
> <font color="#EA0000">**#例外處理(Exception):</br>#不存在的鍵值來取值 - KeyError**</font>
* <font color="#0080FF">**例外處理**</font>
```python=+
grades = {"Joel":80, "Tim":95}
try:
kate_grade = grades["Kate"]
except KeyError:
print("cannot found assign key!!")
```
> ```cannot found assign key!!```
##
* <font color="#0080FF">**字典的 取值方法**</font>
```python=+
grades = {"Joel":80, "Tim":95}
joels_grade = grades.get('Joel',0)
print(joels_grade)
kates_grade = grades.get("Kate",0)
print(kates_grade)
no_ones_grade = grades.get("No One") #get方法不會產生例外
print(no_ones_grade)
```
##
* <font color="#0080FF">**字典的 檢查方法**</font>
```python=+
grades = {"Joel":80, "Tim":95}
grades_keys = grades.keys()
grades_values = grades.values()
#檢查鍵值
print("Joel" in grades_keys)
print("Kate" in grades) #推薦
#檢查對應值(唯一方法)
print(95 in grades_values)
```
> ```True```</br>
> ```False```</br>
> ```True```
> <font color="#EA0000">**#(注意!)字典的鍵值必須是「可湊化的(hashable)」;尤其注意絕不能用列表(list)當作鍵值
#需要多維的鍵值,就應該使用元組,或是把鍵值轉換成一個字串!!**</font>
## 7.Defaultdict
* <font color="#0080FF">**計算整份文件的單詞數量(利用例外處理:先做再說,錯了再補救)**</font>
```python=+
word_counts = {}
def document_counts(document):
for word in document:
try:
word_counts[word] += 1
except:
word_counts[word] = 1
print(word_counts)
```
##
* <font color="#0080FF">**計算整份文件的單詞數量(優雅的作法)**</font>
```python=+
word_counts = {}
def document_counts(document):
for word in document:
previous_count = word_counts.get(word,0)
word_counts[word] = previous_count + 1
```
##
* <font color="#0080FF">**最乾淨俐落的作法 - defaultdict**</font>
```python=+
from collections import defaultdict
word_counts = defaultdict(int) #使用前必須先指定預設 - int()會生成「0」
def document_counts(document):
for word in document:
word_counts[word] += 1
```
##
* <font color="#0080FF">**(續)最乾淨俐落的作法 - defaultdict**</font>
```python=+
dd_list = defaultdict(list)
dd_list[2].append(1) #先建立出空陣列{2:[]} => 再append{2:[1]}
print(dict(dd_list)) #要轉換成dict來使用、查看
dd_dict = defaultdict(dict)
dd_dict["Joel"]["City"] = "Seattle" #先建立出空字典{'Joel':{}} => 再{'Joel': {'City': 'Seattle'}}
print(dict(dd_dict)) #要轉換成dict來使用、查看
dd_pair = defaultdict(lambda : [0,0])
dd_pair[2][1] = 1
print(dict(dd_pair))
```
> ```{2: [1]}```</br>
> ```{'Joel': {'City': 'Seattle'}}```</br>
> ```{2: [0, 1]}```
## 8.計數器 (Counter)
* <font color="#0080FF">**建立一個計數器**</font>
```python=+
from collections import Counter
c = Counter([0,1,2,0]) # c = {'0':2,'1':1,'2':1}
c
```
> ```Counter({0: 2, 1: 1, 2: 1})```
##
* <font color="#0080FF">**計數最常出現的單詞(word)**</font>
```python=+
def document_counts(document):
word_counts = Counter(document)#document 是由許多單詞(word)構成的一個列表
for word,count in word_counts.most_common(10):
#輸出前10個最常用的單詞(word),及其出現次數(count)
print(word,count)
```
## 9.集合 (Set)
> <font color="#EA0000">**#針對set進行in操作,速度非常快(因為重複的元素會被刪除),因此檢查次數減少**</font>
## 10.控制流程 (Process Control)
> <font color="#EA0000">**#if-then-else</br>#while,for,in,continue,break**</font>
## 11.真(True)與假(False)
* <font color="#0080FF">**針對 'None' 的真假判斷**</font>
```python=+
x = None
assert x == None #True
assert x is None #推薦寫法
#assert x is False #若執行此程式碼,則產生例外
```
##
* <font color="#0080FF">**Python 的邏輯判斷**</font>
```python=+
s = 'string'
first_char = s and s[0] # True and True -> 傳回s「0」
print(first_char)
s = ''
first_char = s and s[0] # False and True -> 傳回s
first_char
```
##
* <font color="#0080FF">**(!)(續)Python 的邏輯判斷**</font>
```python=+
#all()函式 -> 其一為False,則結果為False,否則True
a = all([True,1,{3}]) #True
b = all([True,1,{}]) #False
#any()函式 -> 其一為True,則結果為True,否則False
c = any([True,1,{}]) #True
d = any([None,0,{}]) #False
e = all([]) #Ture,因為沒有代表「False」的元素
f = any([]) #False,因為沒有代表「True」的元素
print(a,b,c,d,e,f)
```
## 11.排序 (Sort)
* <font color="#0080FF">**指定函式條件 (Ex.abs) 進行排序**</font>
```python=+
x = [-4,1,-2,3]
x.sort(key = abs,reverse = True)
x
```
> ```[-4, 3, -2, 1]```
##
* <font color="#0080FF">**自訂函式條件 進行排序**</font>
```python=+
def return_Length(ele):
return len(ele)
x = ['Lion','Frog','Dog','Elephant']
y = sorted(x,key = return_Length,reverse = True)
y
```
> ```['Elephant', 'Lion', 'Frog', 'Dog']```
##
* <font color="#0080FF">**(續)自訂函式條件 進行排序**</font>
```python=+
word_counts = {'Lion':3,'Rabbit':5,'Cat':10,"Dog":6}
sort_by_length = sorted(word_counts.items(),key = lambda word_and_counts:len(word_and_counts[0]))
sort_by_counts = sorted(word_counts.items(),key = lambda word_and_counts:word_and_counts[1])
print(sort_by_length) #依照字串長度排列
print(sort_by_counts) #依照出現次數排列
```
> ```[('Cat', 10), ('Dog', 6), ('Lion', 3), ('Rabbit', 5)]```</br>
> ```[('Lion', 3), ('Rabbit', 5), ('Dog', 6), ('Cat', 10)]```
## 12.解析式列表 (List Comprehension)
* <font color="#0080FF">**解析式列表 套入條件判斷**</font>
```python=+
evens = [x for x in range(5) if x%2 == 0]
evens
```
> ```[0, 2, 4]```
##
* <font color="#0080FF">**解析式字典 與 解析式集合**</font>
```python=+
square_dict = {x:x*x for x in range(5)}
square_dict
square_set = {x*x for x in [-2,-1,0,1,2]}
square_set
```
> ```{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}```</br>
> ```{0, 1, 4}```
##
* <font color="#0080FF">**<!>解析式列表 套入多重迴圈**</font>
```python=+
#可有多個for迴圈
pairs = [(i,j) for i in range(5) for j in range(2)]
pairs
```
> ```[(0, 0),(0, 1),(1, 0),(1, 1),(2, 0),(2, 1),(3, 0),(3, 1),(4, 0),(4, 1)]```
##
* <font color="#0080FF">**<!>(續)解析式列表 套入多重迴圈**</font>
```python=+
#後面的迴圈可以使用前面的結果
increasing_pairs = [(x,y) for x in range(5) for y in range(x,x+1)]
increasing_pairs
```
> ```[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]```
## 13.斷言 (Assert)
* <font color="#0080FF">**assert(斷言) 若條件不成立則產生例外**</font>
```python=+
def smallest_items(xs):
assert xs,"空項目不會有最小項" #AssertionError: 空項目不會有最小項(自訂的輸出內容)
return min(xs)
assert smallest_items([5,10,15,20]) == 5
assert smallest_items([])
```
> ```AssertionError: 空項目不會有最小項```
## 14.zip(參數壓合) 與 *(參數拆分)
* <font color="#0080FF">**參數壓合 與 參數拆分**</font>
```python=+
list1 = ['a','b','c']
list2 = [1,2,3]
#zip參數壓合
x = [ele for ele in zip(list1,list2)]
print(x)
#zip參數拆分
alpha,num = zip(*x)
print(alpha,num)
```
> ```[('a', 1), ('b', 2), ('c', 3)]```</br>
> ```('a', 'b', 'c') (1, 2, 3)```
##
* <font color="#0080FF">**(續)參數壓合 與 參數拆分**</font>
```python=+
def add(x,y):return x+y
result = add(*[2,3]) #把list[2,3] 拆分成 2,3
result
```
> ```5```
## 15.args 與 kwargs
* <font color="#0080FF">**將函式做為高階函式的輸入**</font>
```python=+
def doubler(f):
#定義一個新函式g,它會參照到f的結果
def g(x):
return 2*f(x)
return g #這裡要return g(注意!!)
```
##
* <font color="#0080FF">**(續)將函式做為高階函式的輸入 測試**</font>
```python=+
def f1(x):
return x+1
d = doubler(f1)
assert d(3) == 8,"(3+1) * 2 應等於 8"
assert d(-1) == 0,"(-1+1)*2 應等於 0"
#當函式有多個參數就會出問題
#若指定「assert d(1,2)」會出錯,因為d只能接收一個值
```
##
* <font color="#0080FF">**args 與 kwargs 的簡單結構**</font>
```python=+
def magic(*args,**kwargs):
print("unnamed args:",args)
print("keyword args:",kwargs)
magic(1,2,key = 'word',key2 = 'word2')
```
> ```unnamed args: (1, 2)```</br>
> ```keyword args: {'key': 'word', 'key2': 'word2'}```
##
* <font color="#0080FF">**(續)args 與 kwargs 的簡單結構**</font>
```python=+
def other_way_magic(x,y,z):
return x+y+z
x_y_list = [1,2]
z_dict = {"z":3}
#利用*和**為函式提供參數值
assert other_way_magic(*x_y_list,**z_dict) == 6,"1+2+3 應等於 6"
```
## 時間戳記
> [name=ZEOxO][time=Tue, Sep 8, 2020 16:15 PM][color=#907bf7]