首頁  >  問答  >  主體

python - 怎么判断函数或方法多次使用是否需要定义临时变量?

自学一直有一个困扰(因为教程里不太会提及这种问题)
比如一些简单的函数或方法,如 len()isdigit()
多次使用的情况下

string = 'something'
if len(string) == 1:
   pass
elif len(string) == 2:
   pass

是否需要定义一个临时的变量

string = 'something'
length = len(string)
if len(length) == 1:
   pass
elif len(length) == 2:
   pass

这样变量多了一个,但是函数少计算一次
哪一种益处更大呢?
-是所有此类情况都用临时变量呢?
-还是具体函数具体分析,简单的不需要临时变量?
从资源合理利用的角度,怎么权衡这两种方案

PHP中文网PHP中文网2741 天前366

全部回覆(4)我來回復

  • 怪我咯

    怪我咯2017-04-17 17:53:16

    先說結論:

    對於這個問題的情境,我支持不另外定義新的變數


    我先簡單從兩個方面回答你的問題


    首先,當效率不是當前程序的關鍵核心時,以追求 可讀性 為最高原則

    怎麼說呢?

    1. 有些程序和程式碼處理的問題本身就不是追求速度的議題,比如說簡單的寄帳程序跟科學計算比起來,特意追求執行速度的優化不是很有意義,就算是追求效率的程式,也看不見你現在focus 的程式碼就是影響效率的關鍵處(需要作profiling 才能真正確定,過早優化不是很好)。重點是,若非出現效能問題且你已經確定是該程式碼段造成,否則完全不用作資源或效能上的過度考慮,尤其現在機器的空間和運算速度那麼進步的狀況下,一些函數呼叫根本不算什麼,否則oop 和一些抽象化的技巧早就不能用了。

    2. 所以追求可讀性是一般情況下比較好的目標,當然這部分就很看狀況了,比方說Refactoring 這本書裡面就有提到Replace Temp with Query 的手法,因為區域變數可能會使代碼難以被提煉( extract )。但其實也不盡然,有時候過長的 Query 式也會讓程式碼難以閱讀,總之這部分可以有這部分的考量跟權宜。


    第二個部分可以來分析一下效率,以len 而言,我會選擇不另外定義一個變數,因為Python 對於其內建的資料結構,len函數是會直接從對應的C-Object 回傳資料的長度屬性,所以這部分是非常快的,我的意思是,Python 對於自己內建的資料,本身就保存著長度的資訊,使用len 不會造成額外的計算或是層疊的調用,所以完全不必考慮效率問題。 len 而言,我會選擇不另外定義一個變數,因為 Python 對於其內建的資料結構,len 函數是會直接從對應的 C-Object 中回傳資料的長度屬性,所以這部分是非常快的,我的意思是,Python 對於自己內建的資料,本身就保存著長度的資訊,使用 len 不會造成額外的計算或是層疊的調用,所以完全不必考慮效率問題。

    而且 len

    而且 len 的閱讀性很高,函數長度也很短,定義一個新的變數不是很有必要。

    P.S. 若我的理解有誤,請不吝指正,謝謝🎜

    回覆
    0
  • 高洛峰

    高洛峰2017-04-17 17:53:16

    從性能考慮,這種情況確實需要臨時變量,建議養成良好習慣,多用臨時變量並無害處

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-17 17:53:16

    string = 'something'
    length = len(string)
    if length == 1:
       pass
    elif length == 2:
       pass

    先修正程序,在第二版中,len()用一次就可以了,臨時變數也好,也要取個有意義的名字。
    不知道你用時間複雜度有沒有概念,某些演算法一次的時間複雜度是O(N),也就是說,你的字串有n個元素,你的程式就要通過n步才能達到目標,如果你之後還需要m次用到這個演算法的話,那麼你的程式的時間複雜度最少也要n*m步才能完成。 len()用一次就可以了,临时变量也好,也要取个有意义的名字。
    不知道你用时间复杂度有没有概念,某些算法一次的时间复杂度是O(N),也就是说,你的字符串有n个元素,你的程序就要通过n步才能达到目标,如果你之后还需要m次用到这算法的话,那么你的程序的时间复杂度最少也要n*m步才能完成。

    如果你用一个临时变量来记录这个算法,之后通过查值只会用O(1)的时间复杂度,也就是说,你的程序的总复杂度从O(n*m)减少到O(n+m),如果n <= m

    如果你用一個臨時變數來記錄這個演算法,之後透過查值只會用O(1)的時間複雜度,也就是說,你的程式的總複雜度從O(n*m)減少到O(n+m),如果n <= m的話,你的程式時間複雜度就從本來的O(N^2)減少到O(N)了。

    我不太同意多用臨時變數的說法,如果這臨時變數在程式出現頻率<3的話,那麼這個臨時量很可能是不需要的,太多臨時變數會加大程式重構的難度的,是否用臨時變數主要基於以下幾個考量:
    1. 是否大幅減少了程式的時間複雜度?
    2. 是否讓別人更容易理解你的意圖?
    3. 是否能把程式碼看起來更簡潔?
    #🎜🎜#

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-17 17:53:16

    這個問題一般都是因地制宜的,如果只有兩個判斷沒有必要定義變數了,畢竟變數多了不好維護。單就你這個長度而言,如果多個判斷的話,可以用switch case,直接把len()方法作為參數傳進來,並把概率大的選項放在首位。我沒學過Python,不過我覺得switch case這個方法應該有。從我的經驗來看,盡量少定義臨時變量,時間累積長了,變數管理是個很難的事。當然有些地方必須要變量,例如for迴圈的時候,定義一個臨時變數存數組長度會使效能提高一些。總之一切還是從實際出發,當臨時變數能大幅提升目前程式碼的可讀性和維護性時,就需要。否則,就不定義。

    回覆
    0
  • 取消回覆