編程路上,必不可少的編程技巧

  • 2019 年 11 月 20 日
  • 筆記

-Tester-也哥-

在編程的過程中,有很多技巧,但是若不注意,就很容易忽略,即使是高級程式設計師會出現一些問題。今天,就幾個編程技巧,進行一下總結,看看這些你是否有注意到?

根據出現的頻率來調整判斷條件的順序

在寫if…elif…else語句時,可以根據判斷條件出現的頻率來調整順序,使得出現頻率越高的條件,越在前面。這樣可以減少判斷條件的次數,提高程式碼的性能與效率。

例如,在計算成績的時候,大家都清楚成績通常是正太分布的,所以先判斷B和C時,能夠減少判斷的次數,提高程式碼效率,如下所示:

if score > 70 and score < 80:      performance = "B"  elif score > 60 and score < 70:      performance = "C"  elif score > 90:      performance = "A"  else:      performance = "D"

另外,大家應該都比較熟悉短路判斷,即:

if A and B

如果A不滿足的話,不再對B進行比較。所以,在寫程式碼時,可以將不容易滿足的條件設置為A,減少比較次數,提高程式碼效率。

同理,對於

if A or B

當A滿足條件時,則不執行B。所以,大家在寫程式碼時,可以將容易滿足的條件放在A,而不容易滿足的放在B,減少比較次數,提升程式碼品質。

採用快取的機制

相信快取大家已經很熟悉了,Redis,MemoryCache等都是經典的快取實現,但是在程式碼中如何利用快取呢?

這裡,最經典的就是動態規劃。

看這樣一個問題:一個樓梯有10級,每次走1級或兩級,請問從底走到頂一共有多少種走法?比如,每次走1級台階,一共走10步,這是其中一種走法。我們可以簡寫成 1,1,1,1,1,1,1,1,1,1。再比如,每次走2級台階,一共走5步,這是另一種走法。我們可以簡寫成 2,2,2,2,2。當然,除此之外,還有很多很多種走法。

很容易將問題建立模型為:

F(1) = 1

F(2) = 2

F(n) = F(n-1) + F(n-2) (3 <= n <= 10)

採用動態規劃來求解,演算法程式碼如下:

def climbStairs(n):      """      計算n級台階的走法,每次可走1步或者2步      :param n: 台階總數      :return: n級台階的走法      """      if n < 1:          return 0      elif n == 1:          return 1      elif n == 2:          return 2      else:          return climbStairs(n - 1) + climbStairs(n - 2)

熟悉遞歸調用的同學知道,這樣會有很多重複計算。那麼,如何避免重複計算呢?答案很簡單,就是在程式碼中採用快取的機制,當然,也有一些說法是備忘錄機制,大同小異了。演算法程式碼如下:

def climbStairs(n, value):      """      計算n級台階的走法,每次可走1步或者2步      :param n: 台階總數      :param value: 存儲各個不同台階走法的dict      :return: n級台階的走法      """      if value.get(n) is not None:          return value.get(n)      else:          if n < 1:              value[n] = 0          elif n == 1:              value[n] = 1          elif n == 2:              value[n] = 2          else:              value[n] = climbStairs(n - 1, value) + climbStairs(n - 2, value)            return value[n]

另外,在一些計算過程中,對於需要頻繁計算的結果,也可以採用這種快取機制,能夠較好的提升程式碼效率。

簡化相關的數學運算

在編程的過程中,可能會遇到一些數學方面的計算,如果不做簡化的話,將會降低程式碼的效率。這裡比如說,大家都清楚 log()方法返回x的自然對數,對於x>0。但是如果要求以2為底的對數該怎麼辦呢?

通常,根據公式 logb(x) = log(x)/log(b),所以,Python程式碼可以如下:

def log2(x):      import math      return math.log(x)/math.log(2)

實現是沒有問題的,但是效率呢?必然會很低。因為每次都會計算log(2),勢必會增大運算量。如何降低運算量呢?很簡單,將math.log(2)的結果設置為一個常量即可。