[英]Python: lists, mutation, recursion issue
我正在嘗試做的是創建一個最終函數入站,該函數使用一個int(值)列表以及兩個上下兩個整數。 它產生的整數總數小於和小於上限值。 它還會變異值。 如果值的int小於lower,它將使該值變為low;如果值的int大於upper,則將其變為upper。 例如:listin = [-3,82,105,86,-10,119,100,70]入站(listint,0,100)=> 4,並且v突變為[0,82,100,86,0,100,100,70]。
因此,到目前為止,我已經嘗試了兩件事:
我嘗試的第一件事是:
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,但問題是我意識到它只會使values [0]發生變化,因此我嘗試第二次嘗試通過創建另一個具有pos而不是0的函數來解決此問題,並且每次將pos加1遞歸:
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)
問題是入站什么都不做!? 為什么? 當我測試示例時我沒有得到4,並且我得到了沒有任何變化的原始列表...
編輯:我也嘗試更改pos <= len(values)的基本情況,但這仍然行不通
問題是首要條件。 if pos < len(values)
應該是pos >= len(values)
。
另一種方法是使用列表推導:
count = sum(upper <= v <= lower for v in values)
values = [min(upper, max(v, lower)) for v in values] # mutate
第二次嘗試幾乎沒有問題。 您的基本情況是錯誤的-應該是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中應避免遞歸。 這是借用Marat的聰明的min(max())
技巧的Python方法:
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]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.