看列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],要求把列表裏的每一個值加1python
1 >>> a = [i+1 for i in range(10)] 2 >>> a 3 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
列表生成器能夠生成一個動態的列表,如 a = [1,2,3] 那麼是寫死的值算法
至關於app
a = [] for i in range(10): a.append(i+2) print (a)
與列表生成器的區別,當調用的時候纔會去生成對應數據,節省內存空間ide
只有一個__next__()方法函數
只記錄當前的位置。寫一個例子:spa
#生成器 x = (i*2 for i in range(10)) # 創建了算法,但只有調用時纔會出現值 print(x) for j in x: #for 循環調用 print(j)
好比如今有一個斐波那契數 (任意前兩個數相加等於下一個數,除了最開始的數字)線程
1,1,2,3,5,8,13,21,34,56。。。3d
」yield「 code
#yield 返回當前狀態的值,停留函數再此位置能夠隨時回來
#生成斐波那契數列 def fib(max): n, a, b = 0, 0,1 while n <max: yield b #a ,b = 1,2 #至關於 t = (b,a+b) a = 1 b = 2 a+b = 3 #a = t[0] #b = t[1] a,b = b, a + b n = n + 1 #print(fib(10)) f = fib(10) print(f.__next__()) print("乾點別的事此時") print("繼續輸出斐波那契數") print(f.__next__()) print(f.__next__()) print(f.__next__()) print(f.__next__())
牛逼之處:實現單線程下的並行效果(邊吃邊作包子實例):對象
import time def consunmer(name): print("%s 準備吃包子啦!" %name) while True: baozi = yield #yield 返回當前狀態的值,停留函數再此位置能夠隨時回來 print("包子[%s]來了,被[%s]吃了!" %(baozi,name)) #c = consunmer("海州") #c.__next__() #喚醒停留的函數 #c.send("韭菜餡") #喚醒 停留的函數而且傳入一個值進入 def producer(name): c = consunmer("海州") c2 = consunmer("麗佳") c.__next__() c2.__next__() print("老子開始作包子了!") for i in range(10): #循環 time.sleep(1) print("作了1個包子,分兩半!") c.send(i) #遍歷一次i的值給send方法作爲參數,供它喚醒停留的生成器而且傳入值給生成器 c2.send(i) #遍歷一次i的值給send方法作爲參數,供它喚醒停留的生成器而且傳入值給生成器 producer("kim")
如列表、字典、字符可直接做用於for循環
>>> from collections import Iterable >>> isinstance([],Iterable) True >>> isinstance({},Iterable) True >>> isinstance('abc',Iterable) True >>> isinstance((x for x in range(10)),Iterable) True >>> isinstance(100,Iterable) False >>>
能夠用於for循環的對象統稱爲可迭代對象:Iterable
而生成器不但能夠做用於for循環,還能夠被.__next__() 函數不斷調用並返回下一個值,直到最後拋出StopIteration錯誤表示沒法繼續返回下一個值了
能夠被next()函數不斷調用並返回值的對象稱爲:迭代器 Iterator
>>> from collections import Iterator >>> isinstance([],Iterable) True >>> isinstance([],Iterator)
本質爲函數-都使用def關鍵字定義。爲其餘函數添加附加功能
原則一:不能修改被裝飾的函數的源代碼
原則二:不能修改被裝飾的函數的調用方式
實例:
#Herbie Kim #!/usr/bin/python # -*-coding:utf-8-*- import time def timmer(fun): def war(*args,**kwargs): start_time=time.time() fun() stop_time=time.time() print("記錄上面程序運行的時長是%s" %(stop_time-start_time)) return war @timmer def test(): time.sleep(3) print("3秒輸出結果") test()
實現裝飾器的知識儲備
1.函數即「變量」
當x、y 被刪除後內存會被回收,不刪會一直存在
2.高階函數
a. 把一個函數當作參數傳遞給下一個函數 ==》能知足裝飾器之不修改被調用函數的源代碼,但不知足於不修改被調用函數的調用方式
import time def bar(): time.sleep(3) print("in the bar") def fun(test): start_time =time.time() test() #run bar stop_time = time.time() print("the test run time is %s" %(stop_time-start_time)) fun(bar)
b.返回值中包含函數名 ==》知足不修改被調用函數的調用方式
import time def bar(): time.sleep(3) print("in the bar") def fun(test): start_time =time.time() stop_time = time.time() print("the test run time is %s" %(stop_time-start_time)) return test bar = fun(bar) bar()
3.嵌套函數
就函數中再用def定義一個函數,被定義的函數至關於局部變量只做用在此,bar()調用的意義就是在嵌套,bar中的內容是被運行的;不調用就至關於無做爲
def fun(): print("in the fun") def bar(): print("in the bar") bar() fun()
高階函數+嵌套函數 ==》裝飾器
未修改被裝飾的函數的源代碼;未修改被裝飾的函數的調用方式
import time def timer(fun): #調timer(test1) , fun = test1 def doc(): start_time = time.time() fun() #run test1 函數 stop_time = time.time() print("in the func run is %s" %(stop_time-start_time)) return doc @timer #提供的符號表明,test1 = timer(test1) def test1(): time.sleep(3) print("the test1 running") @timer #提供的符號表明,test2 = timer(test2) def test2(): time.sleep(4) print("the test2 running") #test1=timer(test1) test1() #test2=timer(test2) test2()
當有參數須要傳入使,進階方法
import time def timmer(fun): def war(*args,**kwargs): #非固定參數,若是有參數就能夠調用,沒有參數也能夠運行 start_time=time.time() fun(*args,**kwargs) stop_time=time.time() print("記錄上面程序運行的時長是%s" %(stop_time-start_time)) return war #返回結果的內存地址,門牌號 @timmer #test = timmer(test) def test(name,age): time.sleep(3) print("3秒輸出結果",name,age) test("kim",18)