在方法中考慮返回生成器而不是返回列表

方法返回一個序列的最簡單方式就是返回列表,例如想要返回一個句子中全部單詞的位置,下面的代碼通過使用列表來保存單詞的位置並在方法執行結束返回列表:

在方法中考慮返回生成器而不是返回列表

上面方法的簡單調用:

在方法中考慮返回生成器而不是返回列表

雖然對於這類簡單應用不會有任何問題,但是index_words方法還是有兩個問題:

  • 首先,代碼有點醜。。。每次發現一個新的結果時,都需要調用append方法。result.append又需要對結果進行計算(index + 1)。需要一行代碼去計算結果,再需要一行代碼去返回結果。無用代碼太多了。

解決辦法就是使用生成器。生成器就是使用yield的方法。每次調用next方法時,迭代器(iterator)都會在生成器中前進一步。每一個生成器傳遞給yield的值都會通過迭代器返回給調用者。

下面使用生成器重寫以上代碼:

在方法中考慮返回生成器而不是返回列表

此時代碼看起來就清晰多了,因為代碼中沒有過多額外的計算工作了。結果都被直接傳遞給了yield。使用list方法可以很方便的把上面方法返回的迭代器傳換成一個數組。

在方法中考慮返回生成器而不是返回列表

  • 第二個問題也是我們以前常常提到的問題,使用數組作為返回值的話需要在返回結果前計算出所有結果值。如果數據量太大就會導致內存不足。與此對比,生成器就不會佔用太多內存了。

下面我寫了一個新方法,這個方法每次從文件中讀取一行數據,然後每次返回這一行中的一個單詞。這個方法運行時所佔用的最大內存取決於最大行的長度。

在方法中考慮返回生成器而不是返回列表

運行以上代碼:

在方法中考慮返回生成器而不是返回列表

使用生成器需要注意的一點就是,返回結果是有狀態的,不能重複使用。

注意事項:

  • 使用生成器比直接返回數組更清晰;
  • 生成器可以接收任意長度的輸入值。


分享到:


相關文章: