設計 iterator 介面時考慮到了惰性:next(my_iterator) 一次生成乙個元素。懶惰的反義 詞是急迫,其實,惰性求值(lazy evaluation)和及早求值(eager evaluation)是程式語言 理論方面的技術術語。
目前之前部落格的幾版sentence
類都不具有惰性,因為__init__
方法急迫地構建好了文字中的單詞列表,然後將其繫結到self.words
屬性上。這樣就得處理整個文字,列表使用的記憶體 量可能與文字本身一樣多(或許更多,這取決於文字中有多少非單詞字元)。如果只需迭代前幾個單詞,大多數工作都是白費力氣。
只要使用的是 python 3,思索著做某件事有沒有懶惰的方式,答案通常都是肯定的,惰性實現才更符合python語言的規範。
re.finditer
函式是re.findall
函式的惰性版本,返回的不是列表,而是乙個生成器,按 需生成re.matchobject
例項。如果有很多匹配,re.finditer
函式能節省大量記憶體。我們 要使用這個函式讓sentence
類變得懶惰,即只在需要時才生成下乙個單詞。
示例:
import re
import reprlib
re_word = re.compile('\w+')
class sentence:
def __init__(self, text):
self.text = text
def __repr__(self):
# reprlib.repr 這個實用函式用於生成大型資料結構的簡略字串表示形式
return 'sentence(%s)' % reprlib.repr(self.text)
def __iter__(self):
# 迭代 self.words
for match in re_word.finditer(self.text):
yield match.group()
if __name__ == '__main__':
s = sentence('i love python')
ss = iter(s)
print(ss)
print(next(ss))
print(next(ss))
print(next(ss))
print(list(ss))
生成器函式已經極大地簡化了**,但是使用生成器表示式甚至能把**變得更簡短。
簡單的生成器函式,如前面的sentence
類中使用的那個,可以替換成生成 器表示式。
生成器表示式可以理解為列表推導的惰性版本:不會迫切地構建列表,而是返回乙個生成 器,按需惰性生成元素。也就是說,如果列表推導是製造列表的工廠,那麼生成器表示式 就是製造生成器的工廠,其實就是將列表推到中的換成
()
,就行了。
import re
import reprlib
re_word = re.compile('\w+')
class sentence:
def __init__(self, text):
self.text = text
def __repr__(self):
# reprlib.repr 這個實用函式用於生成大型資料結構的簡略字串表示形式
return 'sentence(%s)' % reprlib.repr(self.text)
def __iter__(self):
# 迭代 self.words
# for match in re_word.finditer(self.text):
# yield match.group()
return (match.group() for match in re_word.finditer(self.text))
if __name__ == '__main__':
s = sentence('i love python')
ss = iter(s)
print(ss)
print(next(ss))
print(next(ss))
print(next(ss))
print(list(ss))
唯一的區別是__iter__
方法,這裡不是生成器函式了(沒有yield
),而是使 用生成器表示式構建生成器,然後將其返回。不過,最終的效果一樣:呼叫__iter__
方法 會得到乙個生成器物件。
生成器表示式是語法糖:完全可以替換成生成器函式,不過有時使用生成器表示式更便利。
Python惰性序列
python的iterator就是乙個惰性序列,要說明什麼是惰性序列,首先我們得知道什麼是惰性計算。事實上,很多如j a在內的高階語言都支援惰性序列。引自維基百科 在程式語言理論中,惰性求值 英語 lazy evaluation 又譯為惰性計算 懶惰求值,也稱為傳需求呼叫 call by need ...
Python學習 django惰性機制
django惰性機制 所謂惰性機制 publisher.objects.all 或者.filter 等都只是返回了乙個queryset 查詢結果集物件 它並不會馬上執行sql,而是當呼叫queryset的時候才執行。惰性機制之可迭代 objs models.book.objects.all obj1...
diango中orm的惰性機制
那麼首先要知道什麼是orm 那具體orm是什麼呢?在django中,根據 中的類自動生成資料庫的表也叫 code first orm orm在物件導向模型與關係模型之間架起橋梁。通過物件與資料庫之間對映的元資料,自動透明地把編譯語音中的物件持久化到關聯式資料庫裡,對資料庫的操作可以轉換為對物件的操作...