Python 生成器不該這麼用

pythondict發表於2020-05-13

最近在知乎上有人誤解了Python生成器的使用,在這裡我們來統一探討下它這麼用對不對。

舉一個例子,編寫一個函式計算一串數字裡所有偶數的個數,其實是很簡單的問題,但是有些人是用生成器這麼寫的:


In [66]: def f1(x):

   ....:     return sum(c in '02468' for c in str(x))

   ....: 

In [68]: x = int('1234567890'*50)

In [69]: %timeit f1(x)

10000 loops, best of 5: 52.2 µs per loop 

生成器這麼用其實是速度最慢的一種做法,花費了52微秒。我們來看看如果我改成列表解析式會怎麼樣:


 In [67]: def f2(x):

   ....:     return sum([c in '02468' for c in str(x)])

   ....:  

 In [70]: %timeit f2(x)

 10000 loops, best of 5: 40.5 µs per loop 

你看,這個加速非常地明顯,僅花費了40.5微秒

而且還能進一步改進, 如果我們改變之前定義的f2,讓它在列表解析式後判斷數字是否為偶數,是偶數才會成為最終生成的列表中的一員,這樣有另一個加速:


In [71]: def f3(x):

   ....:     return sum([True for c in str(x) if c in '02468'])

   ....: 

In [72]: %timeit f3(x)

10000 loops, best of 5: 34.9 µs per loop

34.9微秒,Perfect! 不僅如此,還能繼續加速!sum對於整數有一個快速路徑,但是這個快速路徑只啟用型別為int的變數. bool不行,因此我們把True改成1,能再加一次速!


In [73]: def f4(x):

   ....:     return sum([1 for c in str(x) if c in '02468'])

   ....: 

In [74]: %timeit f4(x)

10000 loops, best of 5: 33.3 µs per loop

​Python實用寶典 (pythondict.com)

不只是一個寶典

歡迎關注公眾號:Python實用寶典

原文來自Python實用寶典:Python 生成器

本作品採用《CC 協議》,轉載必須註明作者和本文連結

Python實用寶典, pythondict.com

相關文章