一.用字典映射代替switch case語句 if/else可以代替switch但是非常不合適。 用字典代替switch: day = 5 switcher = { 0:'Sunday', 1:'Monday', 2:'Tuesday' } day_name = switcher.get(day,' ...
一.用字典映射代替switch case語句
if/else可以代替switch但是非常不合適。
用字典代替switch:
day = 5 switcher = { 0:'Sunday', 1:'Monday', 2:'Tuesday' }
day_name = switcher.get(day,'Unknow') print(day_name)
利用get()完整模擬。
在字典中模擬帶函數的switch:
day = 6 def get_sunday(): return 'Sunday' def get_monday(): return 'Monday' def get_tuesday(): return 'Tuesday' def get_default(): return 'Unknow' switcher = { 0:get_sunday, 1:get_monday, 2:get_tuesday } day_name = switcher.get(day,get_default)() print(day_name)
二.列表推導式
根據已經存在的列表創建新的列表:
a = [1,2,3,4,5,6,7,8]
b = [i * i for i in a]
print(b)
#[1, 4, 9, 16, 25, 36, 49, 64]
或者i**2也事代表i的平方。
條件篩選:用列表推導式
a = [1,2,3,4,5,6,7,8]
b = [i**2 for i in a if i >= 5]
print(b)
#[25, 36, 49, 64]
map要結合filter才能實現。
a是集合、字典、元組也可以被推導:
a = {1,2,3,4,5,6,7,8}
b = {i**2 for i in a if i >= 5}
print(b)
三. 字典如何編寫列表推導式
tudents = { 'tai':18, 'park':32, 'a':12 } b = [key for key,value in students.items()] print(b) students = { 'tai':18, 'park':32, 'a':12 } b = {value:key for key,value in students.items()} print(b) students = { 'tai':18, 'park':32, 'a':12 } b = (key for key,value in students.items()) for x in b: print(x)
四. iterator與generator
迭代器:
可迭代對象和迭代器
可迭代對象(iterable):可被for in迴圈遍歷的對象
迭代器(iterator):是一個對象,可被for in迴圈遍歷。一定是個可迭代對象。
普通對象變成迭代器需要實現__iter__()和__next__():
class BookCollection: def __init__(self): self.data = ['《往事》','《只能》','《回味》'] self.cur = 0 def __iter__(self): return self def __next__(self): if self.cur >= len(self.data): raise StopIteration() r = self.data[self.cur] self.cur += 1 return r books = BookCollection() for book in books: print(book)
除了for in 遍歷,還可以調用next方法:
books = BookCollection()
print(next(books))
print(next(books))
print(next(books))
迭代器具有一次性,只能遍歷一次。若想再次遍歷需要實例化一個新的對象。或者:
import copy
books = BookCollection()
books_copy = copy.copy(books) #淺拷貝
若想實現深拷貝的話:
books = BookCollection()
books_copy = copy.deepcopy(books) #生成器
生成器:
列印從0-10000的數字:
n = [i for i in range(0,10001)]
for i in n :
print(i)
可以實現但是太消耗記憶體。n是一個列表,列表存儲需要消耗記憶體的。
更好的方法:生成器
迭代器是針對一個對象的,生成器是針對一個函數的。
函數實現法:
def gen(max):
n = 0
while n <= max:
print(n)
n += 1
gen(100000)
每次列印的都是實時計算出來的結果,不是都存儲起來再列印。
不應該在函數內部實現如print這樣的操作。
生成器:
def gen(max):
n = 0
while n <= max:
n += 1
yield n
g = gen(100000)
next(g)
next(g)
for i in g:
print(i)
yield會接著返回的地方繼續執行。
n = (i for i in range(0,10001))
此時n也為生成器。
五. None
None 空,不等於空字元串、空列表、0、False
不僅在類型上不同,而且在值的比較上也不相同。
class NoneType
判空操作:
def fun():
return None
a = fun()
if not a:
print('s')
else:
print('f')
if a is None:
print('s')
else:
print('f')
#s
#s
如果 a = []則會進入到不同的分支中去。
推薦if a/if not a來判空。
None 不存在,False 假
14-7 對象存在並不一定是True
None永遠對應False
自定義的對象:
class Test():
def __len__(self):
return 0
test = Test()
if test:
print('s')
else:
print('f')
#f #進的是False分支
test存在也有可能是False,需要考慮__len__與__bool__方法。
14-8 __len__與__bool__內置方法
如果沒有定義__len__與__bool__方法則預設為True。
__len__返回0則為False,__len__代表長度,只能用int返回。
例外:__len__可返回True和False
調用len()時,則會調用__len__,如果沒有__len__,求長度的時候會報錯。
一旦加入了__bool__則由__bool__來控制對象的取值。
__bool__只能返回布爾型。
六.裝飾器的副作用
import time def decorator(func): def wrapper(): print(time.time()) func() return wrapper #@decorator def f1(): print(f1.__name__) f1() #f1 #不加裝飾器的函數名字
import time def decorator(func): def wrapper(): print(time.time()) func() return wrapper @decorator def f1(): print(f1.__name__) f1() #1532492964.0116718 #wrapper #加裝飾器的函數名字
wrapper來字閉包函數。
python->help(len)->列印出內置說明
我們可以通過註釋書寫help()的內容
加了裝飾器之後就無法找到函數的help()了
保證名字不改變:
import time from functools import wraps def decorator(func): @wraps(func) def wrapper(): print(time.time()) func() return wrapper @decorator def f1(): print(f1.__name__) f1() #1532493245.2623913 #f1
wraps傳入了原有函數,所以得知了原函數的信息,然後複製到閉包函數上,則信息得以保存。