2017-02-07 3 views
0

То, что я пытаюсь сделать, это создать окончательную функцию inbounds, которая потребляет список значений int (значения) и двух целых чисел ниже и выше. Он производит целое число от общего числа в значениях, которые меньше, чем ниже и выше верхнего. Он также мутирует ценности. Если в значениях, меньших, чем ниже, есть значение int, оно будет мутировать это значение, чтобы опуститься, и существует ли значение int в значениях, превышающих верхний, оно изменит это значение на верхний. 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 и добавить 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 (значения)' –

+0

Извините, не видел, что вы уже пытались сделай это. Вероятно, проблема заключается в том, что вам не хватает возврата в вашу функцию обертки. Это должно быть мутирование оригинала, но я далеко от своего компьютера и не могу играть с ним в данный момент. –

+0

Ах. Ваш базовый случай ошибочен. Он никогда не проходит мимо блока if, потому что он должен быть 'if pos> = len (values)', если вы хотите начать с индекса 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 (значения), все еще получаю тот же ответ. Спасибо, хотя я думаю, я попробую ваш другой подход! – user7526205

+0

Это технически не мутирует «значения». Вам понадобится '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. Вот Pythonic способ заимствования умного 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

 Смежные вопросы

  • Нет связанных вопросов^_^