У меня есть сценарий python, который может получать ноль или три аргумента командной строки. (Либо он работает по умолчанию, либо требует указания всех трех значений.)
Какой идеальный синтаксис для чего-то вроде:
if a and (not b or not c) or b and (not a or not c) or c and (not b or not a):
?
python
if-statement
Крис Уилсон
источник
источник
len(sys.argv)
всегда будет не меньше 1: он включает исполняемый файл какargv[0]
.if not (a and b and c)
(ноль аргументов), а затемif a and b and c
(все три аргумента)?Ответы:
Если вы имеете в виду минимальную форму, сделайте следующее:
Что переводит название вашего вопроса.
ОБНОВЛЕНИЕ: как правильно сказали Volatility и Supr, вы можете применить закон Де Моргана и получить эквивалент:
Я советую использовать ту форму, которая важнее для вас и других программистов. Первое означает «есть что-то ложное, но также и что-то истинное» , второе «Есть что-то истинное, но не все» . Если бы мне пришлось оптимизировать или сделать это аппаратно, я бы выбрал второй, здесь просто выберите наиболее читаемый (также принимая во внимание условия, которые вы будете тестировать, и их имена). Я выбрал первое.
источник
if not (a and b and c) and (a or b or c)
if (a or b or c) and not (a and b and c)
идеальноif any([a,b,c]) and not all([a,b,c])
Как насчет:
Другой вариант:
источник
sum(conditions)
может пойти не так, если,2
например, возврат какой-либо из нихTrue
.sum(map(bool, conditions))
На этот вопрос уже было много высоко оцененных ответов и принятый ответ, но все они до сих пор были отвлечены различными способами выражения логической проблемы и упустили важный момент:
Эта логика не должна лежать в основе вашего кода , скорее, она должна обрабатываться
argparse
модулем. Не утруждайтесь написанием сложного оператора if, вместо этого лучше настроить парсер аргументов примерно так:И да, это должна быть опция, а не позиционный аргумент, потому что это, в конце концов, необязательно .
отредактировано: Чтобы решить проблему LarsH в комментариях, ниже приведен пример того, как вы могли бы написать это, если бы были уверены, что вам нужен интерфейс с 3 или 0 позиционными аргументами. Я считаю, что предыдущий интерфейс лучше по стилю, потому что необязательные аргументы должны быть параметрами , но вот альтернативный подход для полноты картины. Обратите внимание на переопределение kwarg
usage
при создании вашего парсера, потому что вargparse
противном случае автоматически сгенерирует вводящее в заблуждение сообщение об использовании!Вот несколько примеров использования:
источник
Я бы пошел на:
Я думаю, это должно достаточно эффективно закоротить
объяснение
При создании
conds
итератора первое использованиеany
закоротит и оставит итератор, указывающий на следующий элемент, если какой-либо элемент истинен; в противном случае он поглотит весь список и будетFalse
. Следующийany
берет оставшиеся элементы в итерируемом объекте и проверяет, нет ли других истинных значений ... Если есть, то все утверждение не может быть истинным, поэтому нет ни одного уникального элемента (поэтому короткие замыкания очередной раз). Последнийany
либо вернет,False
либо исчерпает итерацию и будетTrue
.примечание: вышеупомянутое проверяет, установлено ли только одно условие
Если вы хотите проверить, установлен ли один или несколько элементов, но не все элементы, вы можете использовать:
источник
[a, b, c] = [True, True, False]
ваш код не должен «печатать»False
, в то время как ожидаемый результат естьTrue
?iter
.any
иall
будет лениво потреблять список, правда, но к тому времени, как вы туда доберетесь, список уже был полностью оценен!Английское предложение:
Переводится в эту логику:
Слово «но» обычно подразумевает союз, другими словами «и». Кроме того, «все они» переводит в сочетание условий: это условие, и это условие, и другое состояние. «Не» полностью инвертирует это соединение.
Я не согласен с принятым ответом. Автор не позаботился о применении наиболее простой интерпретации к спецификации и не применил закон Де Моргана, чтобы упростить выражение до меньшего числа операторов:
утверждая, что ответ - это «минимальная форма».
источник
Это возвращается,
True
если выполнено одно и только одно из трех условийTrue
. Вероятно, то, что вы хотели в своем примере кода.источник
Что насчет: (уникальное состояние)
Обратите внимание: если вы разрешите два условия, вы можете это сделать
источник
1 <= bool(a) + bool(b) + bool(c) <= 2
.Чтобы было ясно, вы хотите принять свое решение на основе того, какая часть параметров имеет логическое значение ИСТИНА (в случае строковых аргументов - не пустые)?
Тогда вы приняли решение:
Теперь логика более понятна.
источник
А почему бы просто не посчитать их?
источник
Если вы не против быть немного загадочным, вы можете просто бросить вызов,
0 < (a + b + c) < 3
который вернется,true
если у вас есть от одного до двух истинных утверждений, и false, если все ложны или ни одно не является ложным.Это также упрощается, если вы используете функции для оценки логических значений, поскольку вы оцениваете переменные только один раз, а это означает, что вы можете писать функции встроенными и не нужно временно хранить переменные. (Пример:.
0 < ( a(x) + b(x) + c(x) ) < 3
)источник
В вопросе указано, что вам нужны либо все три аргумента (a и b и c), либо ни один из них (не (a или b или c))
Это дает:
(a и b и c) или нет (a или b или c)
источник
Насколько я понимаю, у вас есть функция, которая принимает 3 аргумента, но если этого не произойдет, она будет работать по умолчанию. Поскольку вы не объяснили, что должно произойти, когда предоставлены 1 или 2 аргумента, я предполагаю, что он должен просто выполнять поведение по умолчанию. В этом случае, я думаю, вам будет очень полезен следующий ответ:
Однако, если вы хотите, чтобы 1 или 2 аргумента обрабатывались по-разному:
примечание: предполагается, что "
False
" значения не будут передаваться в этот метод.источник
Если вы работаете с итератором условий, доступ к нему может быть медленным. Но вам не нужно обращаться к каждому элементу более одного раза, и вам не всегда нужно читать его полностью. Вот решение, которое будет работать с бесконечными генераторами:
источник
Когда каждый данный
bool
естьTrue
, или когда каждый данныйbool
естьFalse
...все они равны друг другу!
Таким образом, мы просто должны найти два элемента , которые оценивают в разные
bool
с ,чтобы знать , что есть по крайней мере один ,
True
и по крайней мере одинFalse
.Мое короткое решение:
Я верю, что это короткое замыкание, потому что AFAIK
a==b==c
равноa==b and b==c
.Мое обобщенное решение:
Я также написал код, связанный с несколькими итерациями, но удалил его отсюда, потому что считаю это бессмысленным. Однако он все еще доступен здесь .
источник
Это в основном «некоторые (но не все)» функциональность (по контрасту с
any()
иall()
встроенной функцией).Это означает, что среди результатов должны быть
False
s иTrue
s. Таким образом, вы можете сделать следующее:Одним из преимуществ этого кода является то, что вам нужно выполнить итерацию только один раз по результирующим (логическим) элементам.
Одним из недостатков является то, что все эти выражения истинности всегда вычисляются и не производят короткого замыкания, как операторы
or
/and
.источник
.issuperset
вместо того, чтобы просто проверять длину 2,bool
все равно не может вернуть ничего, кроме True и False. Зачем назначать лямбда (читай: анонимная функция) имени вместо простого использования def?return
если вы используетеdef
. я думаю, что универсальность этого решения хороша. нет необходимости ограничиваться логическими значениями, вопрос, по сути, заключается в том, «как мне убедиться, что все эти элементы присутствуют в моем списке». Зачемset
если вам не нужна изменчивость? больше неизменяемости всегда лучше, если вам не нужна производительность.tee
itertools.tee
но 1) я искал однострочник, который был бы простым / достаточно маленьким, чтобы гарантировать копирование-вставку, 2) вы уже дали ответ, который использует эту технику :-)