Hits: 406
python 環境設定
在上課之前,先把python的開發環境布署起來吧,詳細的布署筆記請參考這篇文章
課堂筆記
CH6: Command line in Windows
- 先教command line
* cd: current directory
* cd ..回到上一層
* cd+D+tap,可自動顯示D開頭的資料夾
* cls: clear screen
CH8: Running Python Code
- 可以跑python的環境
- Text Editors
- IDE
- Notebook
- 啟動ipynb
- 在pycharm中安裝
- File>Setting>Project>新增package
CH9
https://github.com/Pierian-Data/Complete-Python-3-Bootcamp
CH10 Introduction to python data types
CH11 Data types簡介
- Integers: 整數
- Float: 浮點小數
- Strings: 字串,python中,可接受"" or ”
- Lists: 有順序的清單
- Dictionaries: 沒順序的key-value配對
- Tuples: 有順序的清單,但內容物不可變更
- Sets: 沒順序的物件
- Booleans: 布林(T or F)
CH12 Numbers
- %得出餘數(remainder)
7 % 4 -- 3
- 開根號(square root)
9 ** 0.5 -- 3
- 次方(power)
2 ** 3 -- 8
CH13 Variable Assignment
- Rules for variable names
- 不能以數字開頭
- 不能有空白
- 不能有特殊符號
- 小寫佳
- Dynamic Typing,下列code是可以運行的,因為python不像其他語言是statitic typing
my_dogs=2
my_dogs=["sammy", "frankie"]
- Dynamic typing的優缺點
- 優點
- 快
- 不用指定資料型別
- 缺點
- data type用在函數中,容易導致資料型別錯誤而產生bug,要特別注意每個input的資料型別
- 優點
- 要注意這樣data type有沒有錯,可使用type()檢查
CH14 Strings
'hello'
or"hello"
都可以,但是建議用"hello"
,因為英文會有遇到"I don't care"
的時候,才不會出錯- 要取順序,是從0開始,也可反著取順序
- slice [start:stop:step]
- 跳脫字元:
- \n這是new line
- \t新增tab
- len(算字元字數)
CH15 Indexing and slicing with strings
mystring='abcdefghijk'
mystring[2:] -> 'cdefghijk' # 類似大於等於2的概念
mystring[:3] -> 'abc' # 類似小於3的概念
mystring[3:6] -> 'def'
mystring[::2] -> 'acegik'
mystring[::-1] -> 'kjihgfedcba' # 字元反轉
CH16 String properties and methods
-
Immutability of string: 字串沒辦法直接修改第幾個字元的內容(doesn’t support item assignment)
name = 'Sam' name[0] = 'P' # TypeError: 'str' object does not support item assignment
-
字串相加用 +
-
字串相乘
-
print(‘z’ * 10) -> zzzzzzzzzz
-
字串切割
-
字串函數
x.upper/lower/split … etcsplit()
要有括號才會執行這個method
'This is a string'.split() -> ['This', 'is', 'a', 'string'] # 以空格分隔
'This is a string'.split(i) -> ['Th', 's ', 's a str', 'ng'] # 把i當作分隔符號來split
CH18 Print with Strings
- 將字串輸出成特別的形式,有兩種方法
- .format() … python 2的舊用法
- f-strings … python 3的新用法
.format的方法
* print('The {2} {1} {0}'.format('fox', 'brown', 'quick')) -> The quick brown fox #.format可以依照位置,填入值
* print('The {q} {b} {f}'.format(f='fox', b='brown', q='quick')) # 也可用變數指派,比較好讀
- Float formatting
- 本功能可用於調整字串的位置
- 設定字串位元數,四捨五入
- 用法:
value:width.precision+f
- value: 變數
- width: 變數的寬
- precision: 小數位數,會四捨五入
result = 100/777 # 0.1287001287001287
print("The result was {r:1.3f}".format(r=result)) -> The result was 0.129
print(f'The result was {result:1.3f}') -> The result was 0.129
f-strings的方法
name = "Jose"
print(f'Hello, his name is {name}') # Hello, his name is Jose
print('Hello, his name is {}.format(name)') # Hello, his name is Jose
CH20 List
mix_list = ['string', 2, 100] # 可以混合資料型態
list1 = ['a', 'b', 'c']
list2 = ['d', 'e']
list1 + list2 -> ['a', 'b', 'c', 'd', 'e']
# 可直接取代
list1[0] = ['gg']
list1 -> ['gg', 'b', 'c']
# 可直接新增(在最後一筆)
list1.append('ggininder') # 注意寫法,這邊會直接對list1執行append()這個method
list1 -> ['gg', 'b', 'c', 'ggininder']
# 可直接移除(可設定index position)
list1.pop()
list1 -> ['gg', 'b', 'c'] # position沒寫,預設為最後一筆(-1)
可排序(sort),但要注意無法另存起來,他會直接把list做變更,沒辦法另存
可反排序(reverse)
CH22 Dictionary
- {‘key1’: ‘value1’, ‘key2’: ‘value2’}
- 要叫出資料要針對key
- dictionary不能被排序,list可以被排序
- dictionary裡面可以再放list或是其他distionary
- 也可直接新增字典內的物件
d = {'k1': 100, 'k2': 120}
d['k3'] = 130
d -> {'k1': 100, 'k2': 120, 'k3': 130}
d.keys() -> ['k1', 'k2', 'k3']
d.values() -> [100, 120, 130]
d.tiems() -> [('k1', 100), ('k2', 120), ('k3', 130)] # it's a tuple
CH24 Tuples: a structure of data that has several parts
- 跟list很像但具有不可修改(immutability)的特性
- tuple = (‘a’,’a’,’b’)
- tuple.count(‘a’) -> 2
- tuple.index(‘a’) -> 0 #傳回第一個a的位置
- Tuple的不具彈性,適合用來
保留不能一直被變更的資料/物件
,list與dictionary則是很有彈性
CH25 Sets
- sets裡面的資料必須是不重複的
- myset=set()
- myset.add(1,1,2) -> {1,2}
CH26 Booleans
- True/False
CH27 I/O with files
- 要開啟檔案,要跟jupyter notebook放在一樣的位置才行
open('file.name')
pwd # 可得知現在的working directory
%%writefile myfile.txt # jupyter notebook限定的建立檔案的方法
This is first line.
This is second line.
This is third line.
myfile = open(myfile.txt)
myfile.read()
>> This is first line.\nThis is second line.\nThis is third line.
#把所有資料讀成一長串字串(包含換行符號) # 讀完之後,要用myfile.seek(0),才能重新讀取一次read()
myfile.readlines()
>>
['This is first line.\n',
'This is second line.\n',
'This is third line.'
]
myfile=open("C:\\path\\ttt.txt") # windows
myfile=open("C:/path/ttt.txt") # Mac/Linux
myfile.close() # 檔案讀進來之後要養成關掉的習慣,才能在OS進行其他操作
# 使用with可以自動關閉檔案,須注意縮排
with open ('myfile.txt') as newfile:
content = newfile.read()content
CH30 object and data structure
作業
CH32 Chaining Comparison Operator
- ‘2’ == 2 -> False
- 2.0 == 2 -> True
- 1 < 2 < 3 -> True
- 1 < 2 > 3 -> False
- 1 < 2 and 2 > 3 -> False
- 1 < 2 or 2 > 3 -> True
- 在所有判斷前加個not,則傳回判斷結果的相反
- not 1 == 1 -> False
CH33 if else
- if, elif, else
- if else elif要在同一個縮排中,execute要在下一個縮排中,要對準
CH35 For loop
- my_iterable就是要被迴圈處理的物件
- item_name就自已取(a,b,c,ee,xx…等諸如此類)
- 範例如下
for num in [1, 2, 3, 4, 5]: # num是在迴圈中會用到的自訂變數名稱,用來代表for迴圈中in後面的每個物件,要被下一行的print(num)來處理
print(num)
>> 1
>> 2
>> 3
>> 4
>> 5
CH35 While loop
-
跟ifelse一樣,要注意縮排
-
while + else
-
break, continue, pass
- break: 停止距離最近的while迴圈
- continue: 從頭(距離最近的while迴圈的第一行)開始進行
- pass: 什麼都別做
-
範例
CH36 Useful Operator
range
是generator,是function裡面的一種類型,可以產出訊息而非存在記憶體中- list(range(0,11,2)) -> [0,2,4,6,8,10]
- enumerate() -> 列舉
# 使用enumerate,回傳物件的自動遞迴並包含自動遞增的整數,以tuples的形式
word = "abcde"
for item in enumerate(word):
print(item)
>> (0, 'a')
>> (1, 'b')
>> (2, 'c')
>> (3, 'd')
>> (4, 'e')
-
zip() -> 像是enumerate的反操作
- 回傳tuples
- 所有要被zip的物件,必須等長,不然只會回傳被zip物件裡面最短的長度
-
in -> 跟
R/SQL
一樣,用來檢查元素是否存在於物件中 -
min, max -> 跟
R
一樣,用來回傳物件中的最小值或最大值 -
from
library
importfunction
-> 從library套件中引用function這個函數python from random import shuffle # 從random套件中引用shuffle函數
-
input -> 產生文字輸入方塊
CH36-1 Import的補充
# 方法1. import [module_name]
import random
print(random.randint(0, 5)) # 使用時要呼叫module_name.method
# 方法1-1. import [module_name] as mn (改名的方法)
import random as rd
print(rd.randint(0, 5)) # 使用時要呼叫rd.randin
# 方法2. from [module_name] import [method1, method2...]
from random import randint
print(randint(0, 5)) # 使用時直接呼叫method
CH37 List Comparison
- 用法與結構:
new_list = [expression for_loop conditions]
- used for creating new lists from other iterables.
- consist of brackets containing the expression, which is executed for each element along with the for loop to iterate over each element.
以單層結構示範
# 單層結構
## 方法1: 迴圈
numbers = [1, 2, 3, 4]
squares = []
for n in numbers:
squares.append(n**2)
print(squares) # Output: [1, 4, 9, 16]
## 方法2: 串列綜合表達(List comprehension)
numbers = [1, 2, 3, 4]
squares = [n**2 for n in numbers]
print(squares) # Output: [1, 4, 9, 16]
多層結構示範
# 多層結構
## 方法1: 迴圈
list_a = [1, 2, 3, 4]
list_b = [2, 3, 4, 5]
common_num = []
for a in list_a:
for b in list_b:
if a == b:
common_num.append(a)
print(common_num) # Output: [2, 3, 4]
## 方法2: List comprehension
list_a = [1, 2, 3, 4]
list_b = [2, 3, 4, 5]
common_num = []
common_num = [a for a in list_a for b in list_b if a == b]
print(common_num) # Output: [2, 3, 4]
回傳 tuple 示範 (以 tuple 列出兩個 list 中不同的元素)
list_a = [1, 2, 3, 4]
list_b = [2, 3, 4, 5]
diff_num = []
diff_num = [(a, b) for a in list_a for b in list_b if a != b]
print(diff_num)
# Output [(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 2), (3, 4), (3, 5), (4, 2), (4, 3), (4, 5)]
兩方法的比較
1. 方法1是比較好閱讀的,雖然比較繁瑣比較多行
2. 方法2是比較難閱讀的,雖然比較簡潔只有一行
其他範例
result = [num ** 2 if num%2 == 0 else 'ODD' for num in range(0,11)] # 很難維護,因為這邊是ifelse先才寫for
print(result)
# Output [0, 'ODD', 4, 'ODD', 16, 'ODD', 36, 'ODD', 64, 'ODD', 100]
CH40 Methods
mylist.append()
-> .append() 就是一種操作清單(list)的方法(method)
- 很多method可以在官方的document找到
Ch41 Function
-
要先用 def開頭,function內可以設變數
-
return可把function結果存起來
# function 可以寫文件
'''
這裡是function的description
'''
def say_hello(name="default_name"): # name是variable,可給予預設值
print("hello " + name)
say_hello()
>> hello default_name
say_hello(frank)
>> hello frank
result = say_hello("frank")
result
>> hello frank
- PIG LATIN example
- word starts with a vowel, add ‘ay’ to end.
- word not starts with a voewl, put first letter at the end, then add ‘ay’
CH43 args(*args
) and kwargs(**kwargs
)
args
: arguments;kwargs
: keyword arguments
*args
-
在使用function時,一定要按照function中定義的參數數量執行,若超過,會出錯
-
args 可以不用指定function內的物件數量,就可以進行運算,在function內使用
*args
會以tuple的形式丟入function中執行
**kwargs
- 跟
*args
一樣,只是**kwargs
是以dictionary的key丟入function中,並回傳value回來
組合*args
與**kwargs
CH49 Lambda expressions map and filter
Lambda function 的一些範例
# 一個參數
print((lambda x:x + 1)(3)) # (3+1) = 4
# 兩個參數
print((lambda x, b:x ** b)(5, 3)) # (5 ** 3) = 125
# 以 function 包起來 - 一個參數
def my_lambda(n):
return lambda b:b ** n
print(my_lambda(5)(2)) # (2 ** 5) = 32
print(my_lambda(2)(5)) # (5 ** 2) = 25
# 以 function 包起來 - 兩個參數
def my_lambda2(n):
return lambda b, c:(b+c) ** n
print(my_lambda2(5)(2, 3)) # (2+3) ** 5 = 3125
Map function
Filter function
Lambda expression(aka anonymous function)
CH50 Nested statements and scope
-
首先說明什麼是LEGB rule:python在找變數時,會從L->E->G->B這四個層級來找變數,根據找到的變數進行函數的指派、程式運作等,LEGB分別代表的意思如下:
- L: local
- E: enclosed function local
- G: global(module)
- B: built-in(python)
-
範例
# 把不同level的name設為註解,可以觀察回吐的name是哪一層
name = 'GLOBAL NAME' # global level
def greet():
name = 'David' # enclosed function local
def hello():
name = 'Local' # local
print("Hello " + name)
hello()
greet()
>> Hello Local
運用LEGB rule說明什麼是變數範圍(Scope)
- global的變數,可以安全的在function中被重新指派,且不會影響到global
x = 50
def func():
print(f'x is {x}')
#Local Reassignment
x = 200
print(f'I change x from 50 to {x}')
func()
>> x is 50
>> I change x from 50 to 200
- 若是要在local的函數中改變global的變數,則使用
global
的指令
x = 50
def func():
global x
print(f'x is {x}')
#Local Reassignment
x = 200
print(f'I change x from 50 to {x}')
func()
print(x)
>> x is 50
>> I change x from 50 to 200
>> 200
- 但是不建議使用
global
指令來修改全域變數,因為會有維護的困難,若要更改全域變數,建議使用下列作法
x = 50
def func(x):
print(f'x is {x}')
# Reassignment
x = 'New'
print(f'I change x from 50 to {x}')
return x
x = func(x)
>>> x is 50
>>> I change x from 50 to New
CH59 Object Oriented Programing
-
allows programmers to create objects that have
methods
andattributes
. -
用class來定義物件(object),也因此可稱呼為類別
-
class通常使用駝峰(Camel casing)來撰寫(ex:
FirstClassNaming
) -
class裡面會用def來定義method
-
init method:用來創建物件實體(instance)的指令
-
用法:init(self,argument1, argument2, …) # self一定要用,用來在class中作為連結class實體與attribute/method的關鍵詞
-
如下範例
CH60 Object Oriented Programing – Attributes and classes keyword
- attribute: is a
characteristic
of an object. - methods: is an
operation
we can perform with the object. - 以下範例說明OOP的基本概念
# 1. 創建自訂Class
class Dog:
# Class object attribute
species = 'mammal' # 加入一個class層別的特性
def __init__(self,mybreed): # mybreed是argument
self.breed = mybreed
# 將mybreed這個argument指派給Class(也就是Dog)內的breed特性(attribute)
# 2. 利用自訂Class指派變數sam與frank
sam = Dog(mybreed='moon')
frank = Dog(mybreed='Huskie')
# 3. 叫出sam與frank的特性
print(sam.breed)
print(frank.breed)
print(sam.species) # 可直接呼叫sam的species這個特性
print(frank.species)
>> moon
>> Huskie
>> mammal
>> mammal
為求方便,在上述程式碼中,一般會將argument, attribute的名稱定為一樣
CH61 Object Oriented Programing – Class object attributes and methods.
- what’s the difference between function and method?
method
is a function inside of a class, work with object, perform operations/actions to object- what’s the difference between atributes and methods?
- method要用(),因為他像是要執行的function,所以要
()
- attribute不用(),因為attribute已經是你執行過的東西,只是要把你執行過的東西叫出來就不用()
- method要用(),因為他像是要執行的function,所以要
class Dog:
species = 'mammal'
def __init__(self, breed, name):
self.breed = breed
self.name = name
def bark(self, number): # number是這個method中要主動提供的參數
print("woo! My name is {}, I bark {} time each day".format(self.name, number)) # self.name是從init繼承來的,number是這個method要主動提供的參數
# 利用自訂Class指派變數sam與frank
sam = Dog(breed='moon', name='sam_dog')
frank = Dog(breed='Huskie', name='frank_dog')
# 叫出sam與frank的特性
print(sam.breed)
print(frank.breed)
print(sam.name)
print(frank.name)
print(sam.species)
print(frank.species)
# 叫出sam與frank的method
sam.bark(3)
>> moon
>> Huskie
>> sam_dog
>> frank_dog
>> mammal
>> mammal
>> woo! My name is sam_dog, I bark 3 time each day
CH62. Object Oriented Programming – Inheritance and Polymorphism
- Inheritance: 就是class可以被繼承而重複使用
# Class Animal
class Animal():
def __init__(self):
print("Animal Created")
def who_am_i(self):
print("I am an animal")
def eat(self):
print("I am eating")
myanimal = Animal()
>> Animal Created
myanimal.eat()
myanimal.who_am_i()
>> I am eating
>> I am an animal
# Class Dog inherited from Animal
class Dog(Animal): # this is a derived class which inheritance from Animal_class
def __init__(self):
Animal.__init__(self) # 繼承Animal.__init__ -> print("Animal Created")
# super().__init__(self) # 或是透過 super() 的函數來繼承
print("Dog Created")
def who_am_i(self):
print("I am a dog!!") # this will overwrite the older method.
mydog = Dog()
>> Animal Created
>> Dog Created
mydog.eat() # mydog裡面沒有eat的method還是可以使用,因為他繼承自Animal這個class
mydog.who_am_i()
>> I am eating
>> I am a dog!!
- Polymorphism: 不同物件可以具有相同的method名稱,且可同時被呼叫使用
# 以下範例,示範使用Animal這個base class後,給Dog與Cat繼承
# 這範例可以發現,Dog與Cat因為繼承與多型性,不需要寫入__init__(已由Animal繼承而來)
class Animal():
def __init__(self,name):
self.name = name
def speak(self): # this is a abstract method because it has no function.
raise NotImplementedError("This is an error.")
class Dog(Animal):
def speak(self):
return self.name + " : Dog says woof"
class Cat(Animal):
def speak(self):
return self.name + " : Cat says meow"
myanimal = Animal("wally")
# myanimal.speak() # will raise the error
wally = Dog("wally")
wally2 = Cat("wally2")
print(wally.speak())
print(wally2.speak())
>> wally : Dog says woof
>> wally2 : Cat says meow
CH63. Special methods
- 這邊講class中的特別method,如
__str__
用於回傳字串表達,__len__
用於計算,__del__
可用於刪除物件,若有需要,可以去官方文件查詢更多的special methods.
CH68. pip install and PyPi
- Pypi is a repository for open source third party python packages.
- 在command line執行
pip install PackageName
就是去pypi抓取套件並安裝於本機
CH69. modules and packages(筆記在ipython notebook)
-
Modules and Packages
.py
scripts就是module,可以讓你的其他程式呼叫.py用- packages就是一系列的module(需包含
__init.py__
)
-
圖解
- 最大的package叫做game,底下有3個次package,分別是Sound, Image, Level
- 最大的package、3個次package都有使用
__init__.py
,這樣python才會把這個資料夾結構看成python package - 每個次package裡面有各自不同的module(aka
py script
),用來處理不同功能所用
# Create modules
## mymodule.py
def my_func():
print("This is mymodule.py")
## program.py
from mymodule import my_func
my_func()
## run in cmd
python myprogram.py
# Create packages
## 開啟一個資料夾(mypackage),#把mymodule.py與program.py丟入
## create __init__.py(裡面不用有任何文字,只要有檔案就可以),用於將folder變成package
## 在mypackage中,建立一個main_script.py
# main_script.py
def report_main():
print("Here is main_script")
## import from package
from mypackag import main_script
main_script.report_main()
CH70. __name__
and __main__
-
為什麼都會在python module的最後一行放入
__name__ == '__main__'
的判斷 -
if __name__ == "__main__" == T
,就代表我正在直接執行one.py
這個檔案 -
if __name__ == "__main__" == F
,代表我這段程式碼one.py
是被imported -
以下範例示範,創造one.py與two.py
# file one.py
def func():
print("func() in one.py")
print("top-level in one.py")
if __name__ == "__main__":
print("one.py is being run directly")
else:
print("one.py is being imported into another module")
# file two.py
import one # 對應到ony.py的else
print("top-level in two.py")
one.func()
if __name__ == "__main__":
print("two.py is being run directly")
else:
print("two.py is being imported into another module")
- 然後在command line中執行
$ python one.py
>>> one.py is being run directly
$ python two.py
>>> one.py is being imported into another module
>>> top-level in two.py
>>> func() in one.py
>>> top-level in one.py
>>> two.py is being run directly
CH71. Errors and exception handling
在我的另外一篇文章寫過了
CH74. Pylint overview
- 可用
pylint
,unittest
來測試 - 使用pylint檢查.py檔案的程式碼是否有問題,還可給出評分,以此為例,還給出負分呢
# this is test.py file
a = 1
b = 2
print(a)
print(B)
$ pip install pylint
$ pylint test.py # 記得要切換到檔案所在的路徑下
************* Module test
D:\test.py:6:0: C0304: Final newline missing (missing-final-newline)
D:\test.py:1:0: C0111: Missing module docstring (missing-docstring)
D:\test.py:3:0: C0103: Constant name "a" doesn't conform to UPPER_CASE naming style (invalid-name)
D:\test.py:4:0: C0103: Constant name "b" doesn't conform to UPPER_CASE naming style (invalid-name)
D:\test.py:6:6: E0602: Undefined variable 'B' (undefined-variable)
-------------------------------------
Your code has been rated at -12.50/10
CH75. Running tests with unittest library
- 建立
cap.py
# create cap.py
def cap_text(text):
return text.capitalize()
- 建立
unitest.py
import unittest
import cap
class TestCap(unittest.TestCase): # 繼承自unittest的attribute: TestCase
def test_one_word(self):
text = "python"
result = cap.cap_text(text) # 繼承自cap.py的method: cap_text
self.assertEqual(result, "Python") # check the result vs 'expected result'
def test_multiple_words(self):
text = "pypi python"
result = cap.cap_text(text)
self.assertEqual(result, "Pypi Python")
if __name__ == '__main__':
unittest.main()
- 看看在shell中的執行結果
$ python unitest.py
======================================================================
FAIL: test_multiple_words (__main__.TestCap)
----------------------------------------------------------------------
Traceback (most recent call last):
File "unitest.py", line 14, in test_multiple_words
self.assertEqual(result, "Pypi Python")
AssertionError: 'Pypi python' != 'Pypi Python'
- Pypi python
? ^
+ Pypi Python
? ^
----------------------------------------------------------------------
Ran 2 tests in 0.002s
FAILED (failures=1)
可以看到shell中執行有錯誤,明確的指出了錯誤原因是test_multiple_words這個method的問題,是因為cap.py
的capitalize()只能轉換第一個字,若改用title()就不會有問題了
CH81 Decorators with python overview
在開發時會碰到一個情境,是原本開發好的的class, method等需要再多增功能。通常的作法就是直接在原本的code裡面新增新的功能,但隨著程式碼越來越龐大,若某天我需要把這個功能取消/擴充時,很容易影響到現在的程式架構,造成維護的困難。
因此﹑python有個功能,叫做裝飾器(decorator),只要在function的前面加上@
,就可,比較常用在web develope的工作上。
在python中,function可以被當成argument傳入另一個function中,return為物件,重複使用,這就是decorator設計的用意。
- 範例
# decorator code
def new_decorator(func):
def wrap_func():
print("Code would be here, before executing the func()")
func() # pass your function here to decorate
print("Code here will execute after the func()")
return wrap_func
# use decorator
@new_decorator
def func_needs_decorator2():
print("Help me to decorate")
# execute
func_needs_decorator2
>>> Code would be here, before executing the func()
>>> Help me to decorate
>>> Code here will execute after the func()
CH83. Generators
- allowing user to generate a sequence of values over time.
- don’t actually return a value and then exit, instead generator functions will automatically suspend and resume the execution and state around the last point of value.
- generator computes one value waits until next value is called.
range
就是個generator- 跟傳統方式相比,就是不用產生一個大的list把所有結果存起來,而是用generator逐步的把東西產出
- 示範使用
next()
與iter()
來逐步產出,讓記憶體使用效率更佳- next()是針對數值物件
- iter()是針對字串物件
# create function that generate fibonacci sequence
def genfibon(n):
"""
Generate a fibonnaci sequence up to n
"""
a = 1
b = 1
for i in range(n):
yield a # aka print(a)
(a,b) = (b,a+b) # tuple assignment
# execute
for num in genfibon(10):
print(num)
>>> 1, 1, 2, 3, 5, 8, 13, 21, 34, 55
# save fibonacci
g = genfibon(10)
g
>>> generator object genfibon at 0x000001E2ED2E8C00
# check the result
next(g)
>>> 1
next(g)
>>> 1
next(g)
>>> 2
next(g)
>>> 3
next(g)
>>> 5
- 以下示範
iter()
s = 'hello'
# Iterate over string
for letter in s:
print(letter)
s_iter = iter(s)
next(s_iter)
>>> 'h'
next(s_iter)
>>> 'e'
next(s_iter)
>>> 'l'
CH87-90. Collection module
Counter
算出物件的重複次數,可用於數字、文字皆可
from collections import Counter
# deal with list
l = [1,1,12,3,1,1,1,2,2,2,3,3,4,5,6,6,7,78,8,8,6,5,4,4]
print(Counter(l))
print(type(Counter(l))) # Counter object
>>> Counter({1: 5, 3: 3, 2: 3, 4: 3, 6: 3, 5: 2, 8: 2, 12: 1, 7: 1, 78: 1})
>>> class 'collections.Counter'
# deal with string
sl = 'asdddssaqaazzbv'
Counter(sl)
>>> Counter({'a': 4, 's': 3, 'd': 3, 'q': 1, 'z': 2, 'b': 1, 'v': 1})
# deal with words(NLP)
words = "How do you turn this on and on and on many times".split()
Counter(words)
>>> Counter({'How': 1,
'do': 1,
'you': 1,
'turn': 1,
'this': 1,
'on': 3,
'and': 2,
'many': 1,
'times': 1})
# attribute
Counter(words).most_common
>>> <bound method Counter.most_common of Counter({'on': 3, 'and': 2, 'How': 1, 'do': 1, 'you': 1, 'turn': 1, 'this': 1, 'many': 1, 'times': 1})>
defaultdict
在dictionary裡面,必須要指定key:value配對
,若沒有配對,是無法直接操作的,使用dafaultdict
可以在沒有指名key:value
的情況下,給予預設的key與value值
from collections import defaultdict
dict = {'k1':1}
d['k1'] >>> 1
d['k2'] >>> KeyError
d = defaultdict(object)
d['one'] >>> <object at memory_location>
d = defaultdict(lambda: 0) # 結合lambda expression
d['two'] = 2
d >>> defaultdict(<function <lambda> at memory_location>, {'two':2, 'one': 0})
OrderdDict
一般在mapping dictionary內的key:value
時,並不會按照順序排序,若要作到這件事情,可使用內建的sorted
# 範例1: 未排序的dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
for k, v in d.items():
print(k, v)
>>> banana 3
>>> apple 4
>>> pear 1
>>> orange 2
# 範例2: 排序的dictionary
ds = sorted(d.items())
for k, v in ds:
print(k, v)
>>> apple 4
>>> banana 3
>>> orange 2
>>> pear 1
namedtuple
利用namedtuple
製造變數
from collections import namedtuple
Dog = namedtuple("Dog", "age breed name")
# 第一個argument是class name, 第二個argument是用空格分隔的attributes
sam = Dog(age = 2, breed = "moon", name = "haha")
print(sam)
print(sam.age)
print(sam.breed)
print(sam.name)
>>> Dog(age=2, breed='moon', name='haha')
>>> 2
>>> moon
>>> haha
CH91. Datetime module
介紹python的時間處理套件Datetime
import datetime
t = datetime.time(5, 25, 1) # hour, minute, second, microsecond, and tzinfo
print(t)
print(t.hour)
>>> 05:25:01
>>> 5
d = datetime.date.today()
print(d)
print(d.year)
print(d.month)
print(d.day)
>>> 2019-04-11
>>> 2019
>>> 4
>>> 11
d1 = datetime.date.today()
d2 = datetime.date(2018,12,31)
d1-d2
>>> datetime.timedelta(days=101)
CH92. Python Debugger
這章介紹python debugger的modeule(pdb
),藉由此module,可產生互動式的測試環境,逐步輸入值,完成除錯
import pdb
x = [1, 3, 4]
y = 2
z = 3
pdb.set_trace() # 產生互動式環境,可輸入值測試
result = y + z
print(result)
result2 = y + x
print(result2)
CH93. Timing your code – timeit
import timeit
# 以下三種表示方式,都可將0到100的數值以'-'相連,可藉由timeit來測試效率
print("-".join(str(n) for n in range(100)))
print("-----")
print("-".join([str(n) for n in range(100)]))
print("-----")
print("-".join(map(str, range(100))))
# 觀察某段程式碼的執行時間
print(timeit.timeit('"-".join(str(n) for n in range(100))', number = 10000))
print(timeit.timeit('"-".join([str(n) for n in range(100)])', number = 10000))
print(timeit.timeit('"-".join(map(str, range(100)))', number = 10000)) # 最快
CH94. Regular expression
CH95. StringIO
把字串變成檔案物件的方法
import StringIO
string = "how do you turn this on"
f = StringIO.StringIO(string)
Comments