2016-08-20 4 views
-1

Может кто-нибудь понять, почему следующий код не удается?Условия обхода

def main(A): 
    A.sort() 
    B = A[:] 
    ll = len(B) 
    while ll > 1: 
     for i in range(ll): 
      for n in range(i + 1, ll): 
       if (B[i] + B[n]) % 2 == 0: 
        B.remove(B[n]) 
        B.remove(B[i]) 
        main(B) 
    return B 
if __name__ == '__main__': 
    result = main([4, 5, 3, 7, 2]) 
    print(result) 

Он работает нормально, пока мой список не имеет только одно значение, достигает оператор «возврат B», а затем он переходит обратно в петлю снова. Что мне не хватает ???

+1

Вы рекурсии, вызов 'основной (B)' и игнорируя возвращаемое значение. Поскольку вы делаете * копию * 'A' каждый раз, игнорируя возвращаемое значение *. –

+0

Я назвал несколько причин, почему ваш код может «провалиться» в моем ответе. Для получения более подробного ответа, включая любой * шанс * в рабочем решении, включите в свой вопрос правильный [mcve]; полный отклик ошибки и ожидаемый результат *, т. е. какая функция * должна делать *. –

ответ

1

Вы используете рекурсию, снова вызывая main(B) в цикле. Когда возвращается рекурсивный вызов, цикл, из которого вы его назвали , продолжается до.

Кроме того, вы игнорируете возвращаемое значение рекурсивных вызовов. Так как вы используете копию списка в каждом вызове main(), игнорирование возвращаемого значения означает, что вы отбросили всю работу, которую рекурсивный вызов выполнил.

И последнее, но не менее важное: вы удаляете элементы из B; вы столкнетесь с ошибками индекса с вашим циклом как i, так и n до ll, длина, которая больше не действует после удаления элементов. Поскольку вы не можете обновить объект range(), который вы зацикливаете; Вы должны были бы использовать while петли, которые проверяют длину каждую итерацию:

i = 0 
while i < len(B): 
    n = i + 1 
    while n < len(B): 
     if (B[i] + B[n]) % 2 == 0: 
      del B[n], B[i] 
      break 
     else: 
      n += 1 
    else: 
     i += 1 

выше цикл будет удалять любые два числа из списка той суммы до четного числа. Обратите внимание, что при удалении значений вы можете использовать индекс , а не искать номер с list.remove().

Внутренняя петля while использует набор else; это выполняется только тогда, когда вы не выходят из цикла, что происходит только в том случае, если мы не просто удаляем значение по индексу i. Поэтому, когда вы не найти спаривание для B[i], i увеличивается, чтобы перейти к следующему кандидату. Если вы do найти спаривание , the value at i is deleted, so now B [i] `уже ссылается на следующее значение.

Я не уверен, почему вам нужно будет рекурсивно после этого цикла; рекурсивный вызов не найдет больше таких пар, поскольку вы проверите все комбинации.

Демонстрация, добавляя при копировании с помощью sorted():

>>> def main(A): 
...  B = sorted(A) 
...  i = 0 
...  while i < len(B): 
...   n = i + 1 
...   while n < len(B): 
...    if (B[i] + B[n]) % 2 == 0: 
...     del B[n], B[i] 
...     break 
...    else: 
...     n += 1 
...   else: 
...    i += 1 
...  return B 
... 
>>> main([4, 5, 3, 7, 2]) 
[7] 
+0

Очень приятное понимание. Спасибо, Мартин Пьетерс. У меня нет ошибок индекса, пока код не «проигнорирует» возвращаемое значение и снова перейдет в цикл. Спасибо еще раз за помощь. –

+0

@VagelisProkopiou: это только потому, что вы не достигли условия ошибки индекса во внешнем цикле **, но **. Он тоже туда попадет. –

+0

Thanx. Ты прав. Кодирование ниндзя действительно! –

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