Chr*_*son 128 python if-statement
我有一个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):
Run Code Online (Sandbox Code Playgroud)
?
def*_*fuz 235
怎么样:
conditions = [a, b, c]
if any(conditions) and not all(conditions):
...
Run Code Online (Sandbox Code Playgroud)
其他变种:
if 1 <= sum(map(bool, conditions)) <= 2:
...
Run Code Online (Sandbox Code Playgroud)
Ste*_*ppo 227
如果您的意思是最小形式,请使用以下内容:
if (not a or not b or not c) and (a or b or c):
Run Code Online (Sandbox Code Playgroud)
这翻译了你的问题的标题.
更新:正如Volatility和Supr所说,您可以应用De Morgan定律并获得等价物:
if (a or b or c) and not (a and b and c):
Run Code Online (Sandbox Code Playgroud)
我的建议是使用对您和其他程序员来说更重要的形式.第一个意思是"有一些错误,但也有一些真实的东西",第二个意思是"有一些东西是真的,但不是一切".如果我要优化或在硬件中执行此操作,我会选择第二个,这里只选择最具可读性(同时考虑您将要测试的条件及其名称).我选了第一个.
wim*_*wim 113
这个问题已经有许多高度赞成的答案和一个公认的答案,但到目前为止所有这些答案都被表达布尔问题的各种方式分散了注意力并错过了一个关键点:
我有一个python脚本,可以接收零或三个命令行参数.(它在默认行为上运行或需要指定所有三个值)
这个逻辑首先不应该是您的代码的责任,而应该由argparse
模块处理.不要费心编写复杂的if语句,而是更喜欢设置你的参数解析器:
#!/usr/bin/env python
import argparse as ap
parser = ap.ArgumentParser()
parser.add_argument('--foo', nargs=3, default=['x', 'y', 'z'])
args = parser.parse_args()
print(args.foo)
Run Code Online (Sandbox Code Playgroud)
是的,它应该是一个选项而不是位置参数,因为它毕竟是可选的.
编辑: 为了解决LarsH在评论中的关注,下面是一个例子,说明如果你确定你想要3或0位置 args的接口你可以编写它.我认为前面的接口是更好的样式,因为可选参数应该是选项,但是为了完整性,这里是另一种方法.usage
在创建解析器时请注意覆盖的kwarg,argparse
否则会自动生成误导性的使用消息!
#!/usr/bin/env python
import argparse as ap
parser = ap.ArgumentParser(usage='%(prog)s [-h] [a b c]\n')
parser.add_argument('abc', nargs='*', help='specify 3 or 0 items', default=['x', 'y', 'z'])
args = parser.parse_args()
if len(args.abc) != 3:
parser.error('expected 3 arguments')
print(args.abc)
Run Code Online (Sandbox Code Playgroud)
以下是一些用法示例:
# default case
wim@wim-zenbook:/tmp$ ./three_or_none.py
['x', 'y', 'z']
# explicit case
wim@wim-zenbook:/tmp$ ./three_or_none.py 1 2 3
['1', '2', '3']
# example failure mode
wim@wim-zenbook:/tmp$ ./three_or_none.py 1 2
usage: three_or_none.py [-h] [a b c]
three_or_none.py: error: expected 3 arguments
Run Code Online (Sandbox Code Playgroud)
Jon*_*nts 32
我会去:
conds = iter([a, b, c])
if any(conds) and not any(conds):
# okay...
Run Code Online (Sandbox Code Playgroud)
我认为这应该相当有效地短路
说明
通过创建conds
一个迭代器,第一次使用any
会短路,如果任何项为真,则将迭代器指向下一个元素; 否则,它将消耗整个列表并且是False
.下一个any
采用iterable中的剩余项,并确保没有任何其他真值...如果有,则整个语句不能为真,因此没有一个唯一元素(如此短路)再次).最后一个any
将返回False
或将耗尽迭代和True
.
注意:以上检查是否只设置了一个条件
如果要检查是否设置了一个或多个项目,而不是每个项目,那么您可以使用:
not all(conds) and any(conds)
Run Code Online (Sandbox Code Playgroud)
Kaz*_*Kaz 22
英文句子:
"如果a或b或c但不是全部"
转换为这个逻辑:
(a or b or c) and not (a and b and c)
Run Code Online (Sandbox Code Playgroud)
"但"这个词通常意味着一个连词,换句话说就是"和".此外,"所有这些"转换为的条件结合:这种情况下,和该条件下,和其它条件."不"反转了整个连词.
我不同意接受的答案.作者忽略了对规范应用最直接的解释,而忽略了应用De Morgan定律来简化表达式给更少的算子:
not a or not b or not c -> not (a and b and c)
Run Code Online (Sandbox Code Playgroud)
同时声称答案是"最小形式".
eum*_*iro 10
这将返回True
如果有且仅有的三个条件之一True
.可能是您在示例代码中想要的内容.
if sum(1 for x in (a,b,c) if x) == 1:
Run Code Online (Sandbox Code Playgroud)
怎么样:(独特的条件)
if (bool(a) + bool(b) + bool(c) == 1):
Run Code Online (Sandbox Code Playgroud)
请注意,如果您也允许两个条件,那么您可以这样做
if (bool(a) + bool(b) + bool(c) in [1,2]):
Run Code Online (Sandbox Code Playgroud)
要清楚,你想根据有多少参数是逻辑TRUE做出决定(如果是字符串参数 - 不是空的话)?
argsne = (1 if a else 0) + (1 if b else 0) + (1 if c else 0)
Run Code Online (Sandbox Code Playgroud)
然后你做出了决定:
if ( 0 < argsne < 3 ):
doSth()
Run Code Online (Sandbox Code Playgroud)
现在逻辑更清晰了.
为什么不算数呢?
import sys
a = sys.argv
if len(a) = 1 :
# No arguments were given, the program name count as one
elif len(a) = 4 :
# Three arguments were given
else :
# another amount of arguments was given
Run Code Online (Sandbox Code Playgroud)
小智 5
如果你不介意有点神秘,你可以简单地滚动,如果你有一到两个真实的陈述0 < (a + b + c) < 3
将返回true
,如果所有都是假或没有假,则返回false.
如果您使用函数来评估bool,这也简化了,因为您只评估变量一次,这意味着您可以内联编写函数,而不需要临时存储变量.(例如:0 < ( a(x) + b(x) + c(x) ) < 3
.)