Python语法“如果a、b或c,但不是全部”

2024-04-19 15:49:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个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):

是吗?


Tags: orand命令行脚本参数if语法not
3条回答

如果你的意思是一个最小的形式,请这样做:

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

翻译你问题的标题。

更新:正如波动率和Supr所正确指出的,您可以应用德摩根定律并获得等价物:

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

我的建议是使用对您和其他程序员更重要的表单。第一个意思是“有虚假的东西,但也有真实的东西”,第二个意思是“有真实的东西,但不是所有的东西”。如果我要在硬件中进行优化或这样做,我会选择第二个,这里只需选择最可读的(还要考虑您将要测试的条件及其名称)。我选了第一个。

怎么样:

conditions = [a, b, c]
if any(conditions) and not all(conditions):
   ...

其他变体:

if 1 <= sum(map(bool, conditions)) <= 2:
   ...

这个问题已经有很多高投票率的答案和一个公认的答案,但到目前为止,所有这些问题都被表达布尔问题的各种方式分散了注意力,错过了一个关键点:

I have a python script that can receive either zero or three command line arguments. (Either it runs on default behavior or needs all three values specified)

这个逻辑不应该首先由代码负责,而应该由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)

是的,它应该是一个选项而不是一个位置参数,因为它毕竟是可选的参数。


编辑:为了解决LarsH在评论中的问题,下面是一个示例,说明如果您确定要使用3或0位置参数的接口,您可以如何编写它。我认为前面的接口是更好的样式,因为可选的参数应该是选项,但是为了完整起见,这里有一种替代方法。注意在创建解析器时重写kwarg usage,因为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)

下面是一些用法示例:

# 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

相关问题 更多 >