Mysql基礎(十五):sql語句執行步驟詳解(四)SQL書寫習慣
一、迭代器
1、什麼是迭代器?
迭代器是訪問物件元素的一種工具。主要是通過迭代的當時來訪問物件裡元素,通常是從第一個元素開始訪問直至最後一個元素訪問結束,每次訪問時都是基於前一個元素的結果。
2、可迭代物件和迭代器
1)可以被for迴圈的物件都是可迭代物件,這些物件內部都有__iter__方法(__iter__方法用於返回一個迭代器)。
2)迭代器不僅有__iter__方法們還有next()方法(用於呼叫迭代器,返回迭代器的下一個元素)
3)迭代器一定是可迭代物件,可迭代物件不一定是迭代器。(list,dict,str都是可迭代物件,但不是迭代器,因為他們沒有next()方法,不能自動訪問自身。需要用for迴圈的next()方法來遍歷自身)
總結:一個實現了__iter__方法的物件是可迭代的,一個實現next方法的可迭代物件是迭代器。
3、判斷迭代器和可迭代物件
from collections import Iterable,Iterator #判斷是否是可迭代物件 print(isinstance([],Iterable)) #True print(isinstance({},Iterable)) #True print(isinstance((),Iterable)) #True print(isinstance("aaa",Iterable)) #True print(isinstance((x for x in range(10)),Iterable)) #True #判斷是否是迭代器 print(isinstance([],Iterator)) #False print(isinstance({},Iterator)) #False print(isinstance((),Iterator)) #False print(isinstance("aaa",Iterator)) #False print(isinstance((x for x in range(10)),Iterator)) #True
判斷是否是迭代器
4、自定義迭代器
#! /usr/bin/env python # -*- coding: utf-8 -*- from collections import Iterable,Iterator class MyRange(object): def __init__(self, n): self.idx = 0 self.n = n def __iter__(self): return self def next(self): if self.idx < self.n: val = self.idx self.idx += 1 return self.n[val] else: raise StopIteration() l = [4,5,6,7,8] obj = MyRange(l) print obj.next() # 4 print obj.next() # 5 print obj.next() # 6 print(isinstance(obj,Iterator)) #True
自定義迭代器
迭代器優點:
1.提供了一種通用不依賴索引的迭代取值方式
2.同一時刻在記憶體中只存在一個值,更節省記憶體
迭代器缺點:
1.取值不如按照索引的方式靈活,不能取指定的某一個值,只能往後取,不能往前去
2.無法預測迭代器的長度
二、生成器
1、什麼是生成器
生成器是一種特殊的迭代器,一般表現為一邊迴圈,一邊計算。
當函式內包含yield關鍵字,呼叫函式不會執行函式體程式碼,會得到一個返回值,該返回值就是生成器物件
2、yield函式
1)只能在函式內使用
2)yield提供了一種自定義迭代器的解決方案
3)yield可以儲存函式的暫停的狀態
4)yield對比return:相同點:都可以返回值,值得型別與個數沒有限制。
不同點:yield可以返回多次值,而return只能返回一次值函式就會結束
3、生成器工作原理
1)生成器是這樣一個函式,它記住上一次返回時在函式體中的位置。
2)對生成器函式的第二次(或第n次)呼叫跳轉至該函式中間,而上次呼叫的所有區域性變數都保持不變。
3)生成器不僅“記住”了它資料狀態;生成器還“記住”了它在流控制構造(在指令式程式設計中,這種構造不只是資料值)中的位置。
4)生成器是一個函式,而且函式的引數都會保留。
5)迭代到下一次的呼叫時,所使用的引數都是第一次所保留下的,即是說,在整個所有函式呼叫的引數都是第一次所呼叫時保留的,而不是新建立的
4、yield生成器執行機制
1)在Python中,yield就是這樣的一個生成器。
2)當你問生成器要一個數時,生成器會執行,直至出現yield語句,生成器把yield的引數給你,之後生成器就不會往下繼續執行。
3)當你問他要下一個數時,他會從上次的狀態開始執行,直至出現yield語句,把引數給你,之後停下。如此反覆
4)在python中,當你定義一個函式,使用了yield關鍵字時,這個函式就是一個生成器
5)它的執行會和其他普通的函式有很多不同,函式返回的是一個物件,而不是你平常所用return語句那樣,能得到結果值。如果想取得值,那得呼叫next()函式
6)每當呼叫一次迭代器的next函式,生成器函式執行到yield之處,返回yield後面的值且在這個地方暫停,所有的狀態都會被保持住,直到下次next函式被呼叫,或者碰到異常迴圈退出。
def fib(max_num): a,b = 1,1 while a < max_num: yield b a,b=b,a+b g = fib(10) #生成一個生成器:[1,2, 3, 5, 8, 13] print(g.__next__()) #第一次呼叫返回:1 print(list(g)) #把剩下元素變成列表:[2, 3, 5, 8, 13]生成器斐波那契