2017-02-07 65 views
0

我想要做的是創建一個最終函數inbounds,它使用int(值)列表和兩個整數lower和upper。它會產生一個小於下限和大於上限值的整數值。它也會改變數值。如果值小於低的int值會將該值改變爲較低值,並且值中的int值大於upper值,則會將該值改變爲upper值。 ex:listin = [ - 3,82,105,86,-10,119,100,70] inbounds(listint,0,100)=> 4,並且v被突變爲[0,82,100,86,0,100,100,70]。Python:列表,突變,遞歸問題

所以我已經試過兩件事情至今:

我想的第一件事是:

def inbounds(values, lower, upper): 
    if values == []: 
     return 0 
    elif lower <= values[0] <= upper: 
     return inbounds(values[1:], lower, upper) 
    elif lower > values[0]: 
     values[0] = lower 
     return inbounds(values[1:], lower, upper) + 1 
    else: 
     values[0] = upper 
     return inbounds(values[1:],lower, upper) + 1 

這並返回4,但這樣做的問題是,我才意識到它只會發生變異值[ 0]所以後來我想我的第2次嘗試通過創建具有代替0 POS另一個功能來解決這個我添加1每次遞歸時間POS:有是

def inbounds_from(values, lower, upper, pos): 
    if pos < len(values): 
     return 0 
    elif lower <= values[pos] <= upper: 
     return inbounds(values, lower, upper, pos+1) 
    elif lower > values[pos]: 
     values[pos] = lower 
     return inbounds(values, lower, upper, pos+1) + 1 
    else: 
     values[pos] = upper 
     return inbounds(values,lower, upper, pos+1) + 1  

def inbounds(values, lower, upper): 
    inbounds_from(values, lower, upper, 0) 

問題是inboun ds什麼都不做!!?爲什麼?我沒有得到4,當我測試的例子,我得到沒有任何突變的原始的名單...

編輯:此外,我試圖更改pos < = len(價值)的基本情況,仍然不工作

+1

你的清單內容,每次遞歸調用,可以返回原始列表的副本的傳球片。您不會看到原始列表中的任何更改。嘗試使用迭代,這是做Python的方式,或者如果你必須使用遞歸,嘗試傳遞當前索引,並增加基本情況爲'index == len(values)' –

+0

抱歉,沒有看到你已經嘗試過去做。問題可能是你在包裝函數中缺少返回。它應該改變原來的,但我遠離我的電腦,目前無法擺弄它。 –

+0

啊。你的基本情況是錯誤的。它永遠不會超過if'塊,因爲它應該是'如果pos> = len(值)'如果你想從索引0開始並且計數... –

回答

1

問題處於第一個狀態。代替if pos < len(values)應該是pos >= len(values)

另一種方法將使用列表理解:

count = sum([v <= lower or v >= upper for v in values]) 
values = [min(upper, max(v, lower)) for v in values] # mutate 
+0

我試過pos <= len(values)仍然得到相同的響應。謝謝,雖然我想我會嘗試你不同的方法! – user7526205

+0

這在技術上不會改變'values'。你需要'values [:] = [

0

有你的第二次嘗試一些問題。你的基本情況是錯誤的 - 它應該是if pos >= len(values)。此外,您正在遞歸包裝函數,而不是助手/內部函數。最後,您需要return調用您的包裝函數中的幫助函數。參見以下內容:

In [4]: def inbounds_from(values, lower, upper, pos): 
    ...:  if pos >= len(values): 
    ...:   return 0 
    ...:  elif lower <= values[pos] <= upper: 
    ...:   return inbounds_from(values, lower, upper, pos+1) 
    ...:  elif lower > values[pos]: 
    ...:   values[pos] = lower 
    ...:   return inbounds_from(values, lower, upper, pos+1) + 1 
    ...:  else: 
    ...:   values[pos] = upper 
    ...:   return inbounds_from(values,lower, upper, pos+1) + 1 
    ...: 
    ...: def inbounds(values, lower, upper): 
    ...:  return inbounds_from(values, lower, upper, 0) 
    ...: 

In [5]: test = [-3,82,105,86,-10,119,100,70] 

In [6]: inbounds(test, 0, 100) 
Out[6]: 4 

In [7]: test 
Out[7]: [0, 82, 100, 86, 0, 100, 100, 70] 

但是,一般來說,在Python中要避免遞歸。這裏是一個Python化的方式借用薩芬的聰明min(max())招:

In [8]: def in_bounds_iter(values, lower, upper): 
    ...:  count = 0 
    ...:  for i, val in enumerate(values): 
    ...:   if not(lower <= val <= upper): 
    ...:    count += 1 
    ...:    values[i] = min(upper, max(val, lower)) 
    ...:  return count 
    ...: 

In [9]: test = [-3,82,105,86,-10,119,100,70] 

In [10]: in_bounds_iter(test, 0, 100) 
Out[10]: 4 

In [11]: test 
Out[11]: [0, 82, 100, 86, 0, 100, 100, 70] 
+0

非常感謝你的幫助和解釋!我不知道我錯過了包裝器函數的遞歸,而不是幫助器......並且在包裝器上添加返回值有很大的意義! – user7526205