2016-10-27 38 views
0

我想做一個程序,返回列表中所有整數的總和,大於n或等於n。例如,Python - 列表中的整數的總和(遞歸)

>>>floorSum([1,3,2,5,7,1,2,8], 4) 
20 

這裏是我想出了代碼:

def floorSum(l,n): 
    if len(l)>0: 
     if l[0]<n: 
      floorSum(l[1:],n) 
     else: 
      s=l[0]+floorSum(l[1:],n) 
    return s 

我越來越:UnboundLocalError: local variable 's' referenced before assignment.

任何想法?

+3

有些路徑通過您的函數不會將任何內容分配給's'。在這些情況下,函數應該返回什麼? – khelwood

+0

@ khelwood是正確的。具體來說,如果'l [0]

+0

@奧利弗不僅僅是這種情況。 'len(l)'爲零的情況也是如此。 – khelwood

回答

-1

Python是一種美妙的語言,它可以讓你在列表理解的單行中做到這一點。

s = sum([value for value in l if value >= n]) 

另一種方法是使用filter

s = sum(filter(lambda e: e >= n, l)) 

第一個基本上說:

「創建從l元素的新名單,讓他們都大於或等於n。總結新清單。「

第二個:

「過濾器僅是大於或等於n薩姆以上的元素。」。

你可以在這兩種技術上找到充足的文檔。

如果你找到了答案很有用,將其標記爲接受

+1

由於OP有一個遞歸標籤並明確指定了主題行中的遞歸,所以這不是一個答案。 – pjs

3

你忘了初始化s

def floorSum(l,n): 
    s = 0 
    if len(l) > 0: 
     if l[0] < n: 
      s = floorSum(l[1:], n) 
     else: 
      s = l[0] + floorSum(l[1:], n) 
    else: 
     return 0 
    return s 
0

謝謝,我解決了這個問題!

忘了把S = 0

+0

您應該標記提供的正確答案 –

2

正如其他人所指出的,你忘了初始化s的所有情況,並檢查長度爲零。

這裏的另一種方法:

def floorSum(l, n): 
    if len(l) > 1: 
     mid = len(l) // 2 # Python 3 integer division 
     return floorSum(l[:mid], n) + floorSum(l[mid:], n) 
    if len(l) == 1 and l[0] >= n: 
     return l[0] 
    return 0 

這個版本將列表分爲兩半的每一步,所以雖然它沒有做任何少工作遞歸堆棧的深度爲O(日誌(LEN (l)))而不是O(len(l))。這將防止大型列表的堆棧溢出。

此方法的另一個好處是額外的存儲要求。 Python在兩個版本中都創建了子列表,但在原始版本中,子列表所需的額外存儲空間爲(n-1) + (n-2) + ... + 1,即O(n )。隨着連續的減半方法,額外的存儲要求是O(n log n),對於大的n值來說,這是非常低的。分配和釋放額外的存儲甚至可能會影響大n的運行時間。 (但是,請注意,這兩種算法都可以通過傳遞感興趣範圍的索引作爲參數而不是創建子列表來避免這種情況。)