簡體   English   中英

Python:清單,變異,遞歸問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM