一、函數的定義
函數是對代碼塊和功能的封裝和定義
#函數的語法:def是define的意思,定義
最基本的語法: def 函數名(): 函數體 函數名() #調用函數
帶有參數的語法 def 函數名(形參列表): 函數體(代碼塊,return) 函數名(實參列表) :調用
#例子:函數執行過程
# def wan(): #定義函數 # print("今天一起去玩") # print("去哪里玩呢") # print("我不知道") # wan() #調用函數 '''講解執行的過程 1.定義函數wan() 2.調用函數wan() 3.准備開始執行函數 4.打印,今天一起去玩 5.打印,去哪里完 6.打印,我不知道 7.函數執行完畢,本次調用完畢,wan()函數調用完畢 '''
二.return返回值的相關操作

return:在函數執行的時候,如果遇到return,則直接返回,和while循環中break一樣 1、如果函數什么都不寫,不寫return,沒有返回值,得到的是Nano 2、在函數中間或者末尾寫return,返回的是None 3、在函數中寫 return 值,返回的是一個值 4、在函數中有返回多個返回值,return 值1、值2、值3... 返回接收到的是元組 #例子: #1、函數什么都不寫,不寫return,返回的是None def wan(): print("今天一起去玩") print("去哪里玩呢") print("我不知道") ret = wan() print(ret) #None #2、在函數中間或者末尾寫return,返回的是None def wan(): print("今天一起去玩") return print("去哪里玩呢") print("我不知道") ret = wan() print(ret) #在執行完第一個print的時候就返回None,就結束了 #3、在函數中寫一個return 值,返回的是一個值 def wan(): print("今天一起去玩") return "鍋蓋" print("去哪里玩呢") print("我不知道") ret = wan() print(ret) #今天一起去玩 #鍋蓋 #會看到返回鍋蓋就結束了 #4、函數中有返回多個返回值,那么返回的是一個元組 def wan(): print("今天一起去玩") return "鍋蓋","番薯","大塊" print("去哪里玩呢") print("我不知道") ret = wan() print(ret) ##('鍋蓋', '番薯', '大塊')
三.函數的參數
函數在調用的時候指定具體的一個變量的值,就是參數
#參數包括:形參,實參,傳參
形參:函數聲明的位置的變量
實參:函數調用的時候給的具體的值
傳參:把實參交給形參的過程
#相關參數具體位置例子
#形參和實參的位置 # def wan(形參): #在函數聲明的位置的變量就是形參 # print(好玩) # # wan(實參) :#在函數調用的地方給的具體的值就是實參 #例子 # def wan(what): # print("手機") # print("去哪里"+what) # wan("廣西") #在調用wan的時候給what一個值,然后執行函數體
#實參的相關操作
#包括 1.位置參數:按照形參的參數位置,給形參傳值 2.關鍵字參數:按照形參的名字給形參傳值 3.混合參數:即用位置參數,也用關鍵字參數
#實參操作的例子:
# 1、位置參數,按照形參的位置,給形參傳值 #例子 # def chi(moning,after,night): # print(moning,after,night) # chi("玉米餃","米飯","面條") #玉米餃 米飯 面條 #2.關鍵字參數: 按照形參的名字給形參傳值 # def chi(moning,after,night): # # print(moning,after,night) # # chi(after="米飯",moning="餃子",night="面條") #餃子 米飯 面條 # 3.混合參數:即用位置參數,也用關鍵字參數 # def chi(moning,after,night): # print(moning,after,night) # chi("餃子","米飯",night="面條") #餃子 米飯 面條 #注意: #順序位置:要先寫位置后再寫關鍵字,要不然會報錯 #例子 # chi("餃子",night="面條","米飯") #會報紅色 #SyntaxError: positional argument follows keyword argument #語法錯誤:關鍵字參數后面跟了位置參數
#形參的相關操作
#包括 1.位置參數 2.默認值參數,要先寫位置參數之后才能寫默認值參數 3.動態參數
包括:位置參數動態傳參 *args,關鍵字參數動態傳參**kwargs
無敵傳參方法:def func(*args,**kwargs):
#形參操作的例子:

#1.位置參數,按照位置來進行賦值 # def chi(moning,after,night): # print(moning) # print(after) # print(night) # chi("餃子","米飯","面條") #2.默認值參數 #例子:比如一個班上要錄入學生信息,有大部分都是男生,就可以設置一個默認值是男 # def stu_inf(name,age,sex='男'): # print("錄入學生信息") # print(name,age,sex) # print("錄入完畢") # stu_inf("蔣小魚",18) # stu_inf("張沖",22) # stu_inf("沈擱",22,sex="女") #如果不想使用默認值也可以自己設定 #注意點: #必須先聲明位置參數,才能聲明默認值參數,否則會有問題 #例子 # def stu_inf(name,sex='男',age): #很明顯這種寫法是錯誤的 #3.位置參數的動態傳參 # * 在這里表示接收位置參數的動態傳參,接收到的是元組 # def chi(*foot): #參數名是food, * 表示動態傳參 # print(foot) # chi("米飯","面條","餃子") #('米飯', '面條', '餃子') # chi("饅頭") # chi() # def chi(name,*food,location="河北"): # print(location) # print(name+"要吃",food) # chi("張三","餃子","面條") #要注意參數的書寫順序 #順序: 位置參數 -> 位置參數動態傳參 -> 默認值參數 #錯誤寫法 # def chi(name,location="河北",*food): # print(location) # print(name+"要吃",food) # chi("張三","餃子","面條") #這樣寫的話餃子就成了默認值 # 餃子 # 張三要吃 ('面條',) ''' #關鍵字的動態傳參 ''' # def chi(**food): # print(food) # # chi(good_food="大米",no_good_food="面條",dirnk="水") #前面得是變量,如果寫數字或者字符串這種就會報錯,如:"大海" = "蝦" # def chi(*food2,**food): #這樣是無敵傳參 # print(food) # # chi(good_food="大米",no_good_food="面條",dirnk="水") #提示: # 位置參數,*args(位置關鍵字動態傳參) 默認值參數 **kwargs 關鍵字動態傳參 # 以上參數可以任意搭配使用,但是要注意順序問題,要不然會有問題
#參數的位置順序排列
位置參數->位置參數動態傳參*args->默認值參數->關鍵字參數動態傳參**kwargs
四.函數的注釋
在函數里面用三個單引號或三個雙引號引起來的就是函數的注釋
#例子:寫好注釋讓別人能看明白,能省去很多事情
# def chi(food,drink): # """ # 這里是函數的注釋,先寫一下當前這個函數是干什么的,不如我這個函數就是一個吃 # :param food: 參數food是什么意思 # :param drink: 參數drink是什么意思 # :return: 返回的是什么東西 # """ # print(food,drink) # return "good" # print(chi.__doc__) #document 文檔 # print(str.__doc__) #查看字符串的文檔注釋
#關於參數的聚合和打散

#形參:聚合 # def func(*food): # print(food) # lst = ["大麻花","餃子","面條","土豆"] # func(lst) #這樣調用的話是一個列表在里面的 # # 實參: 打散 # func(lst[0],lst[1],lst[2],lst[3]) #將上面的大三, 把list,tuple,set,str進行迭代打散 # func(*lst) #上面的打散寫不方便,寫*號更方便簡單 # #但是上面的打散都是一個一個的,那么字典呢? #字典的打散方式 #聚合成關鍵字參數 # def func(**kwargs): # print(kwargs) # dic = {"name":"sir","age":"18"} # func(**dic) #打散成關鍵字參數
五.函數名
函數名也是一個變量,但是一個特殊的變量,與括號配合可以執行函數的變量
#函數名的相關操作
1.函數名可以賦值給其他變量 2.函數名可以作為參數列表中的元素進行存儲,作容器類的元素 3.函數名可以作為參數傳遞給函數 4.函數名可以作為函數的返回值
#函數名相關操作例子:

# 1、函數名的內存地址 # def func(): # print("哈哈") # print(func) #因為還沒有進行調用 #結果:<function func at 0x0000025A9344C1E0> # 2.函數名可以賦值給其他變量 # def func(): # print("哈哈") # # print(func) # a = func #把函數當成一個變量賦值給另一個變量 # a() #函數調用func() #打印哈哈 # 3.函數名可以當作容器類的元素 # def func1(): # print("哈哈") # # def func2(): # print("哈哈") # # def func3(): # print("哈哈") # # lst = [func1,func2,func3] # for i in lst: # i() # 4.函數名可以作為參數傳遞給函數 # def my(): # print("我是my") # # def proxy(fn): # fn() #執行傳遞過來的my # proxy(my) #過程:首先調用proxy函數,將my參數傳遞給proxy,然后變成proxy(my),然后調用my() #接着打印"我是my" #函數名可以作為參數進行傳遞(多層嵌套) # def func(): # print("我是func") # def func1(): # print("我是func1") # # def func2(fn): # print("我是func2") # fn() # func2(func1) #結果:我是func2,我是func1 #解釋:首先執行func2函數,然后有個實參傳遞給形參,打印我是func2,然后執行func1()函數打印我是func1 #例二: # def func(): # print("我是func") # def func1(): # print("我是func1") # # def func2(fn,gn): # print("我是func2") # fn() # gn() # print("hahaha") # func2(func1,func) # 我是func2 # 我是func1 # 我是func # hahaha #解釋:首先執行func2函數,有兩個實參傳遞給形參,打印我是func2,接着執行func1函數打印我是func1, #接着執行funch函數打印我是func,在打印hahaha # 5.函數名可以作為函數的返回值 # def func(): # print("我是func") # a = 10 # 變量 # def inner(): # print("我是inner") # return inner #得出inner,然后使用inner()調用 # print(func) # ret = func() # ret() # func()() #先運行func() 然后再返回值上加()
六.函數的嵌套
1.主要遇見()就是函數被調用了,如果沒有()就不是函數的調用
2.函數的執行順序
#函數嵌套例子

#例子: # def fun(): # print(111) # def fun1(): # print(222) # fun() # fun1() # print(111) #結果是222,111,111 #解釋:定義函數,然后最先調用的是fun1這個函數,所以先的打印fun1中的內容, #接着再調用fun()函數,再打印111,接着再打印111 #例二 # def fun1(): # print("蔣小雨") # def fun2(): # print("魯炎") # def fun3(): # print("張沖") # def fun4(): # print("龍大隊") # fun2() # fun4() # fun3() # def fun5(): # print("二哈") # fun1() # fun5() #二哈,蔣小雨,張沖,龍大隊,魯炎 #分析:首先調用fun5,打印二哈,接着調用fun1,打印蔣小雨,然后調用fun3的函數,打印張沖 #接着執行下面函數體代碼塊,調用fun4,打印龍大隊,接着調用fun2打印魯炎
七.命名空間
把存放名字和值的關系的空間叫做命名空間
#命名空間分類
1.全局命名空間:在py文件中,函數外聲明的變量都屬於全局命名空間 2.局部命名空間:在函數中聲明的變量會放在局部命名空i教案 3.內置命名空間:存放python解釋器為我們提供的名字 如:list,tuple,str,int這些就是內置命名空間
#取值順序
1.局部命名空間 2.全局命名空間 3.內置命名空間 #取值順序例子: a = 10 #全局命名空間 def func(): a = 20 #局部命名空間 print(a) func() #20
八.作用域
定義:作用域就是作用的范圍,按照生效范圍分為:全局作用域和局部作用域
全局作用域:包含內置命名空間和全局命名空間,在整個文件都可以使用
可以通過globals()函數來查看全局作用域中的內容
局部作用域:在函數內部可以使用
可以通過locals()函數來查看局部作用域中的變量和函數信息
#例子:
#例子 # a = 10 # def func(): # a = 40 # b = 20 # def abc(): # print("哈哈") # print(a,b) #這里使用的是局部作用域 # print(globals()) #打印全局作用域中的內容 # print(locals()) #打印局部作用域中的內容 # func()
#關鍵字global和nonlocal講解

global:更改全局變量中的值 理解:在局部中定義一個局部變量,然后加了global,就會將全局中定義的變量的值改成局部的那個變量的值 #global的應用 #例子 # a = 10 # def func(): # global a # a += 10 # print(a) # func() #20 ,加了global就可以改變外部的值了,如果不加是不能更改的 #例如:不加global更改全局參數的時候就會報錯 # a = 10 # def func1(): # a += 10 # print(a) # func1() #總結點:全局變量本身就是不安全的,不能隨意修改 nonlocal:尋找外層函數中離他最近的那個變量 #例子: # a = 10 # def func1(): # a = 20 # def func2(): # nonlocal a # a = 30 # print(a) # func2() # print(a) # func1() # print(a) #30,30,10 #nonlocal是更改離他最近的那個變量,所以,將上一個a=20,改為30 #所以打印是30,30,10,因為nonlocal將20改成了30
九.閉包
定義:在內層函數中訪問外層函數的變量 閉包的作用: 1.可以保護變量不受侵害 2.可以讓一個變量常駐內存
#例子:

#作用例子: #1、保護變量不受侵害 #首先舉一個全局變量不安全的例子 # a = 10 # def outer(): # global a # a = 20 # print(a) # # def outer_2(): # global a # a = 30 # print(a) # # # outer() # outer_2() #得出結果是20,30 #解釋:首先調用outer()函數更改為20,然后再調用outer_2函數打印30 # 這樣就會出現哪個先調用就執行那個,所以改來改去是很混亂的 # def outer(): # a = 10 #這個變量對外界是不開放的 # def func(): # nonlocal a #尋找外層函數中離他最近的那個進行修改 # a = 20 # print(a) # func() # outer() # # def outer_2(): #這個函數不能對a = 10進行修改 # pass #2、讓一個變量常駐內存 # def outer(): # a = 10 #常駐內存,為了inner執行的時候有值,因為你不知什么時候調用 # def inner(): # print(a) # return inner # fn = outer() # print("大大大") # print("笑笑笑") # # fn() #相當於inner(),調用inner函數 #使用 _closure_ 查看函數是不是閉包 #例子:不是閉包的檢測 # def outer(): # def func(): # print("我不是閉包") # print(func.__closure__) #None # outer() #例二:是閉包 # def outer(): # a = 10 # def func(): # print(a) # print(func.__closure__) # outer() #(<cell at 0x000001B7B3E7D978: int object at 0x00007FF97124B470>,) #結論:如果打印的是None,不是閉包,如果不是None,就是閉包
十.迭代器
#迭代器 # 可以簡單理解為:通用的去遍歷某個對象的方式 #有些數據類型是可迭代的,有些是不可迭代的,如果使用不可迭代的來進行循環就會報錯 #例子:使用不可迭代對象來進行循環就會報錯 # s = 123 # for i in s: # print(i) #這樣打印會報錯: TypeError: 'int' object is not iterable:數字不是一個可迭代對象 #那么問題就來了,怎么知道是不是一個可迭代對象呢? #可以通過dir查看xx類型的數據可以執行哪些方法 # print(dir(str)) #__iter__ iterable(可迭代) # print(dir(list)) #__iter__ # print(dir(int)) #如果沒有__iter__,說明不是可迭代對象,不是可迭代對象那么相對應的就不能進行循環 #結論:所有的帶__iter__是可以使用for循環的,是可迭代對象 #可迭代對象就可以使用__iter__()來獲取到迭代器 #迭代器里面有__next__() # s = "我喜歡看火藍刀鋒" # it = s.__iter__() #獲取迭代器 # print(dir(it)) #迭代器里有__iter__ 還有__next__
#迭代器的特點

1.只能向前取,下一個下一個,不能往回 2.幾乎不占用內存,可以有效節省內存 3.for循環 4.惰性機制 #例子: 1.只能向前拿 #print(it.__next__()) #我 # print(it.__next__()) #喜 # print(it.__next__()) #歡 # print(it.__next__()) #看 # print(it.__next__()) #火 2.迭代器模擬for循環 # lst = ["蔣小雨","張沖","魯炎","龍大隊"] # for el in lst: #底層使用的是迭代器 # print(el)
#判斷數據是否可迭代
#例子: # lst = ["張沖","魯炎","蔣小雨"] #it = lst.__iter__() # print("__iter__" in dir(it)) #True # print("__next__" in dir(it)) #True # print(list(it)) #通過dir來判斷數據是否可迭代的,以及數據是否是迭代器 # # #官方方案 # from collections.abc import Iterable #可迭代對象 # from collections.abc import Iterator #迭代器 # # print(isinstance(lst,Iterable)) #True # print(isinstance(lst,Iterator)) #False lst列表本身不是迭代器
十一.生成器
1.生成器的本質就是迭代器,和迭代器的特點一樣,取值方式和迭代器一樣(__next__(),send() 2.在python種有三種方式來獲生成器 1.通過生成器函數 2.通過各種推導式來實現生成器 3.通過數據的轉換也可以獲取生成器
生成器函數
1.函數中如果由yield函數就是生成器函數 2.生成器函數在執行的時候,默認不會執行函數體,會返回生成器 3.yield:相當於return可以返回數據,但是yield不會徹底中斷函數,會分段執行函數 #例子:不執行函數體,拿到的是生成器 # def func(): # print('哈哈') # yield 1 # print('呵呵呵') # gen = func() #這樣子你就會發現不會執行你的函數,拿到的是生成器,如果是return的話就會執行函數了 # print(gen.__next__()) #這樣子就會執行函數,執行到下一個yield,就是說執行看到yield就結束
#生成器應用

#應用場景 # 比如你喜歡吃雞蛋,設想你去市場可以一下子就買一萬個,這樣也是可以,但是有個問題就是雞蛋久了就會爛,存放是個問題,這樣就會很浪費,但是如果你買了個雞回來,就可以解決掉存放空間問題,想什么時候吃就拿一個 #例子:一下子買一萬個浪費 # def egg(): # lst = [] # for i in range(10000): # lst.append('雞蛋'+str(i)) # return lst # ll = egg() #一下子買10000個就會很占用內存 #例二:買只雞,生雞蛋,想吃一個就拿一個 # def egg(): # for i in range(10000): # yield '雞蛋'+str(i) # g = egg() #獲取生成器 # sir = g.__next__() # print(sir) #雞蛋0 # sir1 = g.__next__() # print(sir1) #雞蛋1 #這樣子就是想吃一個就拿一個 #這樣子也驗證了生成器的3個特點 # 1.惰性機制,拿一個才給你取一個 # 2.省內存 # 3.只能向前拿
#send()方法
send()和__next__()是一樣的,可以執行到下一個yield,可以給上一個yield位置傳值 #send和__next__()區別: 1.send和next()都是讓生成器走下一次 2.send可以給上一個yield的位置傳遞值,不能給最后一個yield發送值,在第一次執行生成器代碼的時候不能使用send()
#使用send給上一個yield傳值例子:

#例子:使用send給上一個yield傳值 def func(): print("我吃什么啊") a = yield "玉米" #這里的a和后面的yield是沒關聯的,會把傳進來的值交給print執行 print("a=",a) b = yield "餃子" print("b=",b) c = yield "包子" print("c=",c) yield "OVER" #最后收尾的一定是yield,不然會有報錯 g = func() #獲取生成器,記住有yield的是生成器函數,只會給你獲取到生成器,不會執行函數體 ret1 = g.__next__() #沒有上一個yield,所以不能使用send(),開頭必須__next__() print(ret1) ret2 = g.send("大餅") print(ret2) #a=大餅 ret3 = g.send("粥") print(ret3) #b=粥 ret4 = g.send("冰淇淋") print(ret4) #c=冰淇淋 #解析:執行時候首先我吃什么啊,然后打印玉米,接着ret2使用send上一個yield傳值,所以就變成a=大餅,接着打印a=大餅 # 要注意變量和右邊的yield是兩段來的,互不相干,接着打印餃子,ret3使用send給上一個yield傳值,變成b=粥,接着繼續執行
#生成器可以使用for循環來獲取內部的元素
#為什么生成器可以使用for循環呢,因為生成器實質就是迭代器 #例子: def func(): print(111) yield 222 print(333) yield4444 print(555) yield 666 for i in func(): print(i)
十二.推導式
1.推導式:就是使用一句話來生成 2.包括:列表推導式,字典推導式,集合推導式, 3.注意點:沒有元組推導式 4.3種推導式的語法: 1.列表推導式:[結果 for循環 條件判斷] 2.字典推導式:{k:v for循環 條件判斷} 3.集合推導式:{k for循環 條件判斷}
#3種推導式的應用

#1.列表推導式 語法: [結果 for循環 判斷語句] #例子:首先我們先來一個打印一年級到12年級,我們可能想到的是定義一個空列表,然后把元素追加到列表里面 # lst = [] # for i in range(1,13): # lst.append("年級"+str(i)) # print(lst) #如果使用推導式的話,那么就是使用一句話來生成一個列表 # lst = ["年級"+str(i) for i in range(1,13)] # print(lst) #和上面列表追加一樣的效果 #例二:使用推導式取1-100的奇數 # lst = [i for i in range(100) if i%2 == 1] # print(lst) #例三:尋找名字中帶有兩個e的人的名字 # names = [['Tom','tomi','findall','Wesley','Steven','Jon'],['Alice','Ana','Jennifer','Eva']] #邏輯:首先打開第一層列表,拿到下列表,然后再到小列表里面拿元素,再進行統計判斷 #使用推導式寫 # lst = [name for line in names for name in line if name.count('e') ==2] # print(lst) #['Wesley', 'Steven', 'Jennifer'] #使用常規算法寫 # lst = [] # for line in names: # for name in line: # if name.count('e') == 2: # lst.append(name) # print(lst) #['Wesley', 'Steven', 'Jennifer'] #2.字典推導式 語法:{key:value for循環 條件判斷} #例子:將列表的元素轉換成字典,轉換形式:[11,22,33,44] => {0:11,1:22,2:33} # lst = [11,22,33,44] # dic = {i:lst[i] for i in range(len(lst))} # print(dic) #{0: 11, 1: 22, 2: 33, 3: 44} #例二:將字典的key和value進行調換 # 思路:首先先拿到key和value,然后在推導式的結果那里掉不同位置就可以了 # dic = {"zs":"趙四","ln":"劉能","zc":"張沖","ly":"魯炎"} # d = {v:k for k,v in dic.items()} # print(d) #{'趙四': 'zs', '劉能': 'ln', '張沖': 'zc', '魯炎': 'ly'} #3.集合推導式 #要記住集合的特點:去重,無序,元素必須式可哈希不可變的數據類型 #例1:使用集合推導式去重復 # s = {i for i in range(100)} # print(s) #例二:去重復 # lst= [1,2,3,4,2,1,3,4,6,7] # s = {el for el in lst} # print(s) #{1, 2, 3, 4, 6, 7}
十三.生成器表達式
1.生成器表達式可以直接獲取到生成器對象,生成器對象可以直接進行for循環,生成器具有惰性機制 2.生成器表達式語法: (結果 for 變量 in 可迭代對象 if 條件判斷)
#生成器表達式應用

#下面將演示生成器的最大點特,惰性機制,要拿才給你拿一個,拿走了就沒有值了 # def func(): # print(111) # yield 222 # yield 333 # # a = func() #獲取到生成器 # a1 = (i for i in a) #生成器 # a2 = (i for i in a1) #生成器 # print(list(a)) #[222, 333] # print(list(a1)) #[] # print(list(a2)) #[] #分析:為什么前面的a有值,后面的都沒有值了? #解:因為a是源頭,他從源頭把數據給拿走了,所以后面再從前面拿的話就不會有值了,這就驗證了生成器的惰性機制,你拿一個才給你一個,拿走了就沒有了 #那么后面還能不能獲取到值? 答案是可以的,可以再做一個源頭,再拿數據 #例如:再定義一個a3獲取生成器,再進行調用,這樣子a2就有值了 # def func(): # print(111) # yield 222 # yield 333 # # a = func() #獲取到生成器 # a1 = (i for i in a) #生成器 # a3 = func() # a2 = (i for i in a3) #生成器 # print(list(a)) #[222, 333] # print(list(a1)) #[] # print(list(a2)) #[222, 333] #
#面試題

#題目:計算拿到的值是多少 #求和函數 # def add(a,b): # return a + b #生成器函數 # def test(): # for r_i in range(0,4): # yield r_i # # g = test() #獲取到生成器 # # for n in [2,10]: # g = (add(n,i) for i in g) #上的for可以看成循環量詞 # for n in [2]: # g = (add(n,i) for i in g) # for n in [10]: # g = (add(n,i) for i in g) #因為是2還沒取值,所以是疊加進去,將g換成上面 # g = (add(n,i) for i in (add(n,i) for i in 0,1,2,3) # print(list(g)) #20,21,22,23 #分析:第一個函數是來求和得,第二個函數是生成器函數,沒有打印值,然后到for循環,可以想象是2和10都執行了一次,但是因為生成器得惰性機制,然后執行2是沒有值,所以是不關2的事情,執行10得時候才會執行,將10帶進去算 #最后的執行是這樣:g = (add(10,i) for i in (add(10,i) for i in 0,1,2,3),所以就成10+10,10+11,10+12,10+13 #提示:惰性機制,不到最后是不會拿值得 #下面接着演示列表有多個值,但是它只會看最后面的那個,前面的會相加 # def add(a,b): # return a + b #生成器函數 # def test(): # for r_i in range(0,4): # yield r_i # g = test() #獲取到生成器 # # for n in [1,3,7]: # g = (add(n,i) for i in g) #這個就是相當於疊加了3次 # g = (add(7,i) for i in (add(7,i) for i in (add(7,i) for i in 0,1,2,3) # print(list(g)) #21,22,23,24 #最后的運算是:(add(7,i) for i in (add(7,i) for i in (add(7,i) for i in 0,1,2,3) #將7帶進去運算,把最后那個帶進去算 #首先是0+7,1+7,2+7,3+7,接着7+7,7+8,7+9,7+10,然后7+14,7+15,7+16,7+17
#生成器表達和列表推導式的區別
1.生成器表達式比較省內存,列表推導式比較耗內存
2.得到的值不一樣,列表推導式得到的是一個列表,生成器表達式獲取的是生成器