迭代器模式:一種惰性獲取數據項的方式,即按需一次獲取一個數據項。
專注于為中小企業提供成都網站制作、網站建設、外貿網站建設服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業祁縣免費做網站提供優質的服務。我們立足成都,凝聚了一批互聯網行業人才,有力地推動了上1000+企業的穩健成長,幫助中小企業通過網站建設實現規模擴充和轉變。
所有序列都是可以迭代的。我們接下來要實現一個 Sentence(句子)類,我們向這個類的構造方法傳入包含一些文本的字符串,然后可以逐個單詞迭代。
接下來測試 Sentence 實例能否迭代
序列可以迭代的原因:
iter()
解釋器需要迭代對象 x 時,會自動調用iter(x)。
內置的 iter 函數有以下作用:
由于序列都實現了 __getitem__ 方法,所以都可以迭代。
可迭代對象:使用內置函數 iter() 可以獲取迭代器的對象。
與迭代器的關系:Python 從可迭代對象中獲取迭代器。
下面用for循環迭代一個字符串,這里字符串 'abc' 是可迭代的對象,用 for 循環迭代時是有生成器,只是 Python 隱藏了。
如果沒有 for 語句,使用 while 循環模擬,要寫成下面這樣:
Python 內部會處理 for 循環和其他迭代上下文(如列表推導,元組拆包等等)中的 StopIteration 異常。
標準的迭代器接口有兩個方法:
__next__ :返回下一個可用的元素,如果沒有元素了,拋出 StopIteration 異常。
__iter__ :返回 self,以便在需要使用可迭代對象的地方使用迭代器,如 for 循環中。
迭代器:實現了無參數的 __next__ 方法,返回序列中的下一個元素;如果沒有元素了,那么拋出 StopIteration 異常。Python 中的迭代器還實現了 __iter__ 方法,因此迭代器也可以迭代。
接下來使用迭代器模式實現 Sentence 類:
注意, 不要 在 Sentence 類中實現 __next__ 方法,讓 Sentence 實例既是可迭代對象,也是自身的迭代器。
為了“支持多種遍歷”,必須能從同一個可迭代的實例中獲取多個獨立的迭代器,而且各個迭代器要能維護自身的內部狀態,因此這一模式正確的實現方式是,每次調用 iter(my_iterable) 都新建一個獨立的迭代器。
所以總結下來就是:
實現相同功能,但卻符合 Python 習慣的方式是,用生成器函數代替 SentenceIteror 類。
只要 Python 函數的定義體中有 yield 關鍵字,該函數就是生成器函數。調用生成器函數,就會返回一個生成器對象。
生成器函數會創建一個生成器對象,包裝生成器函數的定義體,把生成器傳給 next(...) 函數時,生成器函數會向前,執行函數定義體中的下一個 yield 語句,返回產出的值,并在函數定義體的當前位置暫停,。最終,函數的定義體返回時,外層的生成器對象會拋出 StopIteration 異常,這一點與迭代器協議一致。
如今這一版 Sentence 類相較之前簡短多了,但是還不夠慵懶。 惰性 ,是如今人們認為最好的特質。惰性實現是指盡可能延后生成值,這樣做能節省內存,或許還能避免做無用的處理。
目前實現的幾版 Sentence 類都不具有惰性,因為 __init__ 方法急迫的構建好了文本中的單詞列表,然后將其綁定到 self.words 屬性上。這樣就得處理整個文本,列表使用的內存量可能與文本本身一樣多(或許更多,取決于文本中有多少非單詞字符)。
re.finditer 函數是 re.findall 函數的惰性版本,返回的是一個生成器,按需生成 re.MatchObject 實例。我們可以使用這個函數來讓 Sentence 類變得懶惰,即只在需要時才生成下一個單詞。
標準庫提供了很多生成器函數,有用于逐行迭代純文本文件的對象,還有出色的 os.walk 函數等等。本節專注于通用的函數:參數為任意的可迭代對象,返回值是生成器,用于生成選中的、計算出的和重新排列的元素。
第一組是用于 過濾 的生成器函數:從輸入的可迭代對象中產出元素的子集,而且不修改元素本身。這種函數大多數都接受一個斷言參數(predicate),這個參數是個 布爾函數 ,有一個參數,會應用到輸入中的每個元素上,用于判斷元素是否包含在輸出中。
以下為這些函數的演示:
第二組是用于映射的生成器函數:在輸入的單個/多個可迭代對象中的各個元素上做計算,然后返回結果。
以下為這些函數的用法:
第三組是用于合并的生成器函數,這些函數都可以從輸入的多個可迭代對象中產出元素。
以下為演示:
第四組是從一個元素中產出多個值,擴展輸入的可迭代對象。
以下為演示:
第五組生成器函數用于產出輸入的可迭代對象中的全部元素,不過會以某種方式重新排列。
下面的函數都接受一個可迭代的對象,然后返回單個結果,這種函數叫“歸約函數”,“合攏函數”或“累加函數”,其實,這些內置函數都可以用 functools.reduce 函數實現,但內置更加方便,而且還有一些優點。
參考教程:
《流暢的python》 P330 - 363
這幾個函數在 Python 里面被稱為高階函數,本文主要學習它們的用法。
filter 函數原型如下:
第一個參數是判斷函數(返回結果需要是 True 或者 False),第二個為序列,該函數將對 iterable 序列依次執行 function(item) 操作,返回結果是過濾之后結果組成的序列。
簡單記憶:對序列中的元素進行篩選,獲取符合條件的序列。
返回結果為: ,使用 list 函數可以輸入序列內容。
map 函數原型如下:
該函數運行之后生成一個 list,第一個參數是函數、第二個參數是一個或多個序列;
下述代碼是一個簡單的測試案例:
上述代碼運行完畢,得到的結果是: 。使用 print(list(my_new_list)) 可以得到結果。
map 函數的第一個參數,可以有多個參數,當這種情況出現后,后面的第二個參數需要是多個序列。
map 函數解決的問題:
reduce 函數原型如下:
第一個參數是函數,第二個參數是序列,返回計算結果之后的值。該函數價值在于滾動計算應用于列表中的連續值。
測試代碼如下:
最終的結果是 6,如果設置第三個參數為 4,可以運行代碼查看結果,最后得到的結論是,第三個參數表示初始值,即累加操作初始的數值。
簡單記憶:對序列內所有元素進行累計操作。
zip 函數原型如下:
zip 函數將可迭代的對象作為參數,將對象中對應的元素打包成一個個元組,然后返回由這些元組組成的列表。
如果各個迭代器的元素個數不一樣,則返回列表長度與最短的對象相同,利用星號( * )操作符,可以將元組解壓為列表。
測試代碼如下:
展示如何利用 * 操作符:
輸出結果如下:
簡單記憶:zip 的功能是映射多個容器的相似索引,可以方便用于來構造字典。
enumerate 函數原型如下:
參數說明:
該函數用于將一個可遍歷的數據對象組合為一個索引序列,同時列出數據和數據下標,一般用在 for 循環當中。
測試代碼如下:
返回結果為: 。
本文涉及的函數可以與 lambda 表達式進行結合,能大幅度提高編碼效率。最好的學習資料永遠是官方手冊
數學上面的定義:迭代公式就是指用現在的值,代到一個公式里面,算出下一個值,再用下一個值代入公式,如此往復地代。比如:x=(x+2/x)/2 你隨便拿一個x=10代入,得x=(10+2/10)/2=5.1,再代進去x=(5.1+2/5.1)/2=2.746,再代入得1.737,以此類推。
在python中,迭代式也可以是遞歸的調用,下面給你舉個例子:
def f(n):
if n == 0 or n == 1 or n == 2: return 1
else: return f(n-1) + f(n-2)
這就是一個簡單的第n項斐波那契數的求法,這里就用的是迭代式。另外的例子就是牛頓迭代法,采用逐次漸進的效果求出n的開方數,下面是例子:
def f(guess):
return guess ** 2
def fd(guess):
return 2 * guess
def SquareRootNR(x, epsilon):
guess = x / 2.0
diff = f(guess) - x
ctr = 1
while abs(diff) epsilon and ctr = 100:
guess = guess - diff / fd(guess)
diff = f(guess) - x
ctr += 1。
1、map
map()函數接受兩個參數,一個是函數,一個是Iterable,map將傳入的函數依次作用到序列的每一個元素上,并把結果作為新的Iterator返回。
舉例,比如我們有一個函數f(x)=x*2,要把這個函數作用在一個list[1, 2, 3, 4, 5, 6, 7, 8,
9]上,就可以用map()實現。
def f(x):
... return x*2
...
r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
list(r)
[2, 4, 6, 8, 10, 12, 14, 16, 18]
所以,map()作為高階函數,事實上它把運算規則抽象了,因此,我們不但可以計算簡單的f(x)=x*2,還可以計算任意復雜的函數,比如把這個list所有的數字轉為字符串:
list(map(str,[1, 2, 3, 4, 5, 6, 7, 8, 9]))
["1", "2", "3", "4", "5", "6", "7", "8", "9"]
2、reduce
reduce是把一個函數作用在一個序列[x1, x2,
x3……]上,這個函數必須接收兩個參數,reduce把結果繼續和序列的下一個元素做累計計算。簡單來說,就是先計算x1和x2的結果,再拿結果與x3計算,依次類推。比如說一個序列求和,就可以用reduce實現。
from functools import reduce
def add(x, y):
... return x + y
...
reduce(add, [1, 3, 5, 7, 9])
25
也就是說,假設python沒有提供int()函數,你完全可以自己寫一個把字符串轉化為整數的函數,而且只需要幾行代碼。
3、filter
用于過濾序列,和map函數類似,filter也接收一個函數和一個序列,不同于map的是,filter把傳入的函數依次作用于每一個元素,然后根據返回值是True還是False決定保留還是丟棄該元素,例如,在一個list中,刪掉偶數,只保留奇數,可以這么寫:
def is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 結果: [1, 5, 9, 15]
把一個序列中的空字符串刪掉,可以這么寫:
def not_empty(s):
return s and s.strip()
list(filter(not_empty, ["A", "", "B", None, "C", " "]))
# 結果: ["A", "B", "C"]
可見用filter()這個高階函數,關鍵在于正確實現一個篩選函數。
4、sorted
無論冒泡排序還是快速排序,排序的核心是比較兩個元素的大小。如果是數字,我們可以直接比較,但如果是字符串或者兩個dict呢?直接比較數學上的大小是沒有意義的,因此,比較的過程必須通過函數抽象出來,Python內置的sorted()函數就可以對list進行排序:
sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]
此外,sorted()函數也是一個高階函數,它還可以接收一個key函數來實現自定義的排序,例如按絕對值大小排序:
sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
新聞標題:python高階迭代函數 python迭代法求高次方程
文章位置:http://m.newbst.com/article18/dojesgp.html
成都網站建設公司_創新互聯,為您提供面包屑導航、ChatGPT、建站公司、定制開發、搜索引擎優化、品牌網站設計
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯