Обход условий

python python-3.x if-statement while-loop

47 просмотра

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)

Он работает нормально до тех пор, пока в моем списке только одно значение, не достигнет оператора return B, а затем снова возвращается в цикл. Что мне не хватает ???

Автор: Vagelis Prokopiou Источник Размещён: 08.11.2019 11:05

Ответы (1)


1 плюс

Решение

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

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

И последнее, но не менее важное: вы удаляете элементы из B; вы будете сталкиваться с ошибками индексации с вашим циклом как iи nrange 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

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

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

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

Демо, добавление в копирование с помощью 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]
Автор: Martijn Pieters Размещён: 20.08.2016 09:03
Вопросы из категории :
32x32