Логическая эквивалентность последовательности предложений if else if else

Я серьезно недосыпаю, и мне нужна помощь в переписывании этого небольшого фрагмента логики Python.

for _ in range(100):
    if a:
        continue
    elif b:
        continue
    elif c and d:
        continue
    else:
        e()

Я хочу иметь что-то вроде

if (some_exprt of a,b,c,d):
    e()

Что я получил:

if not a and  not b and (not c or not d):
   e()

но я действительно не могу сказать, правильно это или нет, я прав?


person baibo    schedule 10.12.2013    source источник
comment
Что именно ты пытаешься сделать?   -  person Inbar Rose    schedule 10.12.2013
comment
Попробуйте подумать об этом снизу вверх. Выполнить e(), если ни a, ни b, ни c, ни d не верны   -  person Burhan Khalid    schedule 10.12.2013
comment
Вы можете использовать De_Morgan's_laws, чтобы преобразовать свой ответ в тот, что дает @Martijn.   -  person John La Rooy    schedule 10.12.2013
comment
@InbarRose зацикливается и пропускает нежелательные итерации   -  person baibo    schedule 10.12.2013
comment
Простые условия лучше сложных, и continue тоже подойдет (см., например, llvm.org/docs/). Просто замените elifs на ifs, и все готово.   -  person georg    schedule 10.12.2013


Ответы (3)


Начните с того, при каких условиях ветвь else не будет соответствовать. Это будет один из a, или b, или c and d, поэтому вам нужно будет использовать or и not здесь, чтобы указать, когда будет выбрана ветвь else вашего исходного кода:

if not (a or b or (c and d)):
    e()

Затем вы можете поставить not в скобки, применив один из законов Де Моргана, выражающий предыдущий тест более подробно как:

if not a and not b and not (c and d):
    e()

который затем может быть расширен до:

if not a and not b and (not c or not d):
    e()

это то, к чему вы сами уже расширились. Но я бы нашел первую версию более читабельной.

person Martijn Pieters    schedule 10.12.2013

continue не может работать внутри оператора if. Итак, я предполагаю, что вы запускаете это внутри цикла (пока или для). Попробуй это:

#whatever loop
if not(a or b or (c and d)):
    e()

Второй подход без not будет:

if a or b or (c and d):
    continue
else:
    e()

Как объяснил М. Мартин Петерс в комментариях, блок else во втором подходе не нужен. Вы можете удалить else и переместить e() за пределы блока if. Однако, на мой взгляд, else после if сделает код более читабельным.

Второй подход также может быть записан как:

if a or b or (c and d):
    continue
e()
person thiruvenkadam    schedule 10.12.2013
comment
Я, я расширю контекст - person baibo; 10.12.2013
comment
Я думаю, мы можем предположить, что оператор if был единственным кодом в цикле. - person Martijn Pieters; 10.12.2013
comment
Это безопасное предположение :-) Я просто хотел уточнить для OP, что continue нельзя использовать в блоке if, если он пытается :-) - person thiruvenkadam; 10.12.2013
comment
Если вы продолжаете в любом случае, вы можете просто отбросить вызов else и сместить вызов e(). if a or b or (c and d): continue новая строка e(). - person Martijn Pieters; 10.12.2013
comment
@MartijnPieters Верно. Спасибо. Я обновлю код. Спасибо. - person thiruvenkadam; 10.12.2013

person    schedule
comment
Это будет оценивать a, b и c (и, возможно, d) перед вызовом any(). Это не приведет к короткому замыканию, когда a оценивается как ложное значение. Это может быть важно. - person Martijn Pieters; 10.12.2013