目錄 python
1.迭代器算法
2.生成器閉包
3.推導式app
4.匿名函數函數
5.內置函數spa
6.遞歸日誌
7.閉包對象
8.裝飾器blog
一.迭代器排序
特色:
1. 省內存
2. 只能向前. 不能反覆
3. 惰性機制
讓不一樣的數據類型有相同的遍歷方式
迭代器取值方法:
lst = [1,2,3,4]
lst1 = lst.__iter__()
print(next(lst1))
print(lst1.__next__())
判斷是否是可迭代對象和迭代器
from collections import Iterator,Iterable
lst = [1,2,3,4]
print(isinstance(lst,Iterable)) 可迭代對象
print(isinstance(lst,Iterator)) 迭代器
用while循環打印迭代器並異常捕捉
lst = ["黑色星期天","bad feel","滾吧","那就這樣吧"]
lst1 = lst.__iter__()
while True:
try:
s = lst1.__next__()
print(s)
except StopIteration:
break
dir() 查看咱們數據類型能夠執行的操做
二.生成器
生成器本質上也是一個迭代器,特色也是節省空間。經過yield來定義
def func():
yield
生成器函數 -> 執行的時候. 不會當即把函數所有執行完. 建立一個生成器返回給你
省內存
__next__() 能夠拿到數據
send() 能夠拿到數據, 能夠給生成器傳遞消息 send會給上一個yield傳遞參數。
普通打印例子:
def order():
lst = []
for i in range(1000):
lst.append("衣服" + str(i))
return lst
lst = order()
print(lst) ps:當數據量多大內存容易出問題
生成器例子:
def order():
lst = []
for i in range(100):
yield "衣服" + str(i)
gen = order()
print(gen.__next__()) ps:要一個值打印一下next便可,惰性機制的特色。
send應用
def func():
print("韭菜盒子")
s1 = yield 1
print("s1=", s1)
print("沙琪瑪")
s2 = yield 2
print("s2=", s2)
print("盒飯")
s3 = yield 3
print("s3=", s3)
print("混沌")
s4 = yield 4
gen = func()
print(gen.__next__()) # send能夠給上一個yield位置傳值
ret1 = gen.send("周潤發")
ret2 = gen.send("周杰倫")
ret3 = gen.send("周筆暢")
print("===============")
print(ret1)
print(ret2)
print(ret3) ps:send是給上一個yield傳值,不能給最後一個yield傳值,不然會報錯
三.推導式
列表推導式:
[結果 for循環 if語句]
例子1:lst = ["python週末班%s" % i for i in range(1, 27) if i%2==0 ]
print(lst)
例子2:把姓張的人檢索出來, 放在一個新列表裏 startswith
lst = ["歐陽娜娜", "張崔猛", "歐陽難過", "張亞無照", "胡一飛", "胡怎麼飛", "張炸輝"]
print([name for name in lst if name.startswith("張")])
例子3:使用列表推導式獲得 [1, 4, 9, 16, 25, 36]
print([i*i for i in range(1,7)])
例4在[3,6,9]的基礎上推到出[[1,2,3], [4,5,6],[7,8,9]]
print([[i-2,i-1,i] for i in [3,6,9]])
字典推導式:
{key:value for if}
例1:經過列表推導成字典
lst = ["張三丰", "張無忌", "張翠山"]
print({i:lst[i] for i in range(len(lst))})
集合推導式
{key for if}
print({i for i in range(10)})
沒有元組推導式!!!!!!!
生成器表達式:
(結果 for if)
gen = (i for i in range(10))
print(gen)
for i in gen:
print(i)
四.匿名函數
匿名函數語法:
匿名函:lambda 參數: 返回值 配合內置函數一塊兒使用 不能寫太多
func = lambda x:x*10
print(func(10))
例1:給函數傳遞一個參數,返回字符串的長度
lambda args: len(args)
五.內置函數
repr() 字符串表示形式
zip() 拉鍊函數
sorted() 排序
例子1:
lst = ["高進", "波多野結衣", "蒼老師", "倉木麻衣", "紅狗"]
s = sorted(lst,key=lambda s: len(s))
print(s) ps:首先,打開這個可迭代對象. 而後獲取到每一項數據. 把每一項數據傳遞給函數,根據函數返回的數據進行排序.
例2:按照年齡大小排序
lst = [{"id":1, "name":'alex', "age":18},
{"id":2, "name":'wusir', "age":16},
{"id":3, "name":'taibai', "age":17}]
def func(d):
return d["age"]
s = sorted(lst,key=func,reverse=True)
print(s)
filter()帥選函數
例1:篩選出大於20的數字
st = [18, 22, 66, 35, 1, 48]
f = filter(lambda n:n>20,st)
for item in f:
print(item) ps:返回迭代器, 把可迭代對象中的每一項數據交給前面的函數. 由函數決定該數據是否保留
例2:打印大於或者等於18歲的成年人
lst = [{"id":1, "name":'alex', "age":18},
{"id":2, "name":'wusir', "age":16},
{"id":3, "name":'taibai', "age":17}]
s = filter(lambda n:n["age"]>=18,lst)
for i in s:
print(i)
map() 會根據提供的函數對指定序列作映射
lst = [2,5,3,2,4]
m = map(lambda n:n*n, lst)
for i in m:
print(i) ps:python2 裏面返回來的是列表,python3返回的是迭代器
六.遞歸
特色:實際上就是函數本身調本身,永遠不可能超過1000層
遞歸死循環
i = 0
def func():
global i
i +=i
print("哈哈" ,i)
func()
func()
傳統的查找方法須要一個個對比很消耗資源
lst = [12,24,53,67,108,267]
n = 798
for i in range(len(lst)):
if lst[i] == n:
print("I found it")
else:
print("didn't find it")
遞歸用法
def binarySearch(lst, n, left, right):
if left <=right: # 判斷是否已經查找完畢
mid = (left+right)//2 # 計算中間
if n > lst[mid]: # 數據比中間大
left = mid + 1 # 作邊界拉倒右邊
# 進入遞歸
return binarySearch(lst, n, left, right)
elif n < lst[mid]:
right = mid - 1
return binarySearch(lst, n, left, right)
else:
print("找到了")
return mid
else:
print("沒找到")
return -1
lst = [12,24,53,67,108,267]
n = 108
ret = binarySearch(lst, n, 0, len(lst)-1)
print(ret)
二分法,一個最簡單的算法,用於查找某個數字
n = 108
lst = [12,24,53,67,108,267]
left = 0
right = len(lst) - 1 # 右邊界
while left <= right:
mid = (left + right)//2
if n > lst[mid]:
left = mid+1
elif n < lst[mid]:
right = mid-1
else:
print("找到了")
print(mid)
break
else:
print("沒有") ps:兩頭掐尾取中間。
七.閉包
做用:在內層函數中使用外層函數的變量
1.保護變量
2.讓一個變量常駐內存
定義:
def outer():
a = 10
def inner():
print(a)
return inner
outer = outer()
outer()
查看函數是否是閉包:
def outer():
a = 10
def inner():
print(a)
return inner
fn = outer()
ret = fn()
print(fn.__closure__)
八.裝飾器
簡潔版語法
def func(fn):
def inner():
print("hahaha")
fn()
print("make a go")
return inner
@func
def func1():
print("我要離開地球表面")
func1()
精版
def func(fn):
def inner(*args,**kwargs):
print("hahaha")
ret = fn(*args,**kwargs)
print("make a go")
return ret
return inner
@func
def func1(*args,**kwargs):
print("我要離開地球表面")
return "流光幸運刀"
ret = func1("我要流光幸運刀")
print(ret)
ps:上面的裝飾器當用戶查看本身的函數時就能看出來就閉包。能夠經過以下方法來掩飾
from functools import wraps
def waiguai(fn):
@wraps(fn )
def inner(*args,**kwargs):
print("開外掛")
ret = fn(*args,**kwargs)
print("結束外掛")
return ret
return inner
@waiguai
def dnf(username,password):
print("starting game")
@waiguai
def king(qq):
print("王者")
dnf1 = dnf("ivy","wang")
print(dnf1)
king("1327285005")
print(king.__name__)
給裝飾器傳遞參數
例子1:給裝飾器傳遞一個值若是是True問金老闆不然直接直接fn()
主要實現原理是先執行@後面的函數而後在執行@,至關於分紅兩部分來實現。
def outer(flag):
def decoration(fn):
def inner(*args,**kwargs):
if flag:
print("問問金老闆去哪兒好")
ret = fn(*args,**kwargs)
print("金老闆騙人的")
else:
ret = fn(*args, **kwargs)
return ret
return inner
return decoration
@outer(True)
def dating():
print("約帥哥。。。")
dating()
print("--------華麗麗的分割線------------")
@outer(False)
def travel():
print("想一想去哪兒。。。")
travel()
例子2,日誌打印,重要的日誌放在一指定的文件下面,不重要的放在默認路徑下。
import time
def outer(filename="default.log"):
def decoration(fn):
def inner(*args,**kwargs):
print("打印訪問日誌" )
with open(filename,mode="a",encoding="utf-8") as f:
f.write("在%s 訪問了%s \n" % (time.strftime("%Y-%m-%d %H:%M:%S"),fn.__name__))
ret = fn(*args,**kwargs)
return fn
return inner
return decoration
@outer("func1.log")
def func1():
print("Hello everyong I am func1")
func1()
@outer()
def func2():
print("Hello everyone I am func2")
func2()
ps: func1的日誌打印到func1.log裏面,func2的日誌打印到default.log 裏面,主要基於裝飾器傳參定義默認參數來實現的。
多個裝飾器裝飾一個函數
def decoration1(fn):
def inner():
print("before decoration1")
fn()
print("after decoration1")
return inner
def decoration2(fn):
def inner():
print("before decoration2")
fn()
print("after decoration2")
return inner
def decoration3(fn):
def inner():
print("before decoration3")
fn()
print("after decoration3")
return inner
@decoration1
@decoration2
@decoration3
def func():
print("hello I am the real funcation")
func()
打印結果
因而可知多個裝飾器裝飾一個函數的原理,是一層層來實現的,最開始執行的是離函數最近的那個開始的。