本文是《Effect Python 編寫高質量Python代碼的59個有效方法》的學習筆記。主要記錄生成器的使用方法和示例代碼。
返回隊列的函數
如果函數要產生一系列結果,那么最簡單的做法就是把這些結構都放在一份列表里,然后將其返回給調用者。
def index_words(text): """用append方法將這些此的首字母索引添加到result列表中,并在函數結束時將其返回給調用者。""" result = [] if text: result.append(0) for index, letter in enumerate(text): if letter == ' ': result.append(index+1) return result
輸入一些測試值,驗證該函數能正常運行:
>address = 'Four score and seven years ago...'result = index_words(address)print(result[:3])
打印
[0, 5, 11]
生成器函數
這個函數改用生成器(generator)來寫會更好。生成器是使用yield表達式的函數。調用生成器函數時,它并不會真的運行,而是會返回迭代器。每次在這個迭代器上面調用內置的next函數時,迭代器會把生成器推進到下一個yield表達式那里。生成器傳給yield的每一個值,都會由迭代器返回給調用者。
def index_words_iter(text): if text: yield 0 for index, letter in enumerate(text): if letter == ' ': yield index + 1
result = list(index_words_iter(address))
注意:生成器函數返回的迭代器是有狀態的,調用者不應該反復使用。
由于迭代器只能產生一輪結果。在拋出過StopIteration異常的迭代器或生成器上面繼續迭代第二輪,是不會有結果的。為解決此問題,我們可以明確地使用該迭代器制作一份列表,將它的全部內容都遍歷一次,并賦值到這份列表里,然后就可以在復制出來的數據列表上面多次迭代了。
為類實現生成器
下面是一個可以迭代的容器類,用來從文件中讀取每行數據。
class ReadFileLines(object): """ 可以迭代的容器類,從文件中獲取數據 """ def __init__(self, path): self.path = path def __iter__(self): with open(self.path) as f: for line in f: yield line
多次迭代
如果想多次迭代生成器的數據,可以使用下面的函數。該函數會逐步拷貝生成器的所有數據,然后返回一個隊列數據。
def normalize_defensive(datas): """ 從生成器返回一份可以多次迭代的數據 :param datas:容器 :return: result:隊列(list) """ # 確保調用者傳進來的參數,并不是迭代器對象本身 if iter(datas) is iter(datas): raise TypeError('Must supply a container') # TODO result = [] for data in datas: # TODO result.append(data) return result總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VEVB武林網的支持。
新聞熱點
疑難解答