[python] “a 또는 b 또는 c 인 경우 모두에 대한 것은 아닙니다”에 대한 Python 구문

0 또는 3 개의 명령 행 인수를 수신 할 수있는 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):

?



답변

최소한의 형태를 의미한다면 다음과 같이하십시오.

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

질문 제목을 번역합니다.

업데이트 : Volatility and Supr에서 올바르게 말했듯이 De Morgan의 법칙을 적용하고 동등한 것을 얻을 수 있습니다.

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:
   ...


답변

이 질문은 이미 많은 찬사를 받았으며 받아 들여진 대답이 많았지 만 지금까지 부울 문제를 표현하는 다양한 방법으로 혼란스러워하고 중요한 요점을 놓쳤습니다.

0 또는 3 개의 명령 행 인수를 수신 할 수있는 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)

그리고 네, 그것은 선택적 인수이기 때문에 위치 인수가 아닌 옵션 이어야합니다 .


편집 : 주석에서 LarsH의 우려를 해결하기 위해 아래는 3 또는 0 위치 인수가있는 인터페이스를 원한다면 어떻게 작성할 수 있는지에 대한 예입니다. 선택적 인수는 options 이어야하기 때문에 이전 인터페이스가 더 나은 스타일이라고 생각합니다.그러나 여기에는 완전성을위한 대체 접근법이 있습니다. 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)

사용 예는 다음과 같습니다.

# 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


답변

나는 갈 것이다 :

conds = iter([a, b, c])
if any(conds) and not any(conds):
    # okay...

나는 이것이 상당히 효율적으로 단락되어야한다고 생각한다.

설명

conds반복자 를 만들면 , anywill 의 첫 번째 사용 은 단락되고 어떤 항목이 참이면 반복자가 다음 요소를 가리키게합니다. 그렇지 않으면 전체 목록을 소비하고입니다 False. 다음 any은 iterable의 나머지 항목을 가져 와서 다른 실제 값이 없는지 확인합니다.있는 경우 전체 문이 사실이 될 수 없으므로 고유 한 요소가 없습니다 (짧은 회로 다시). 마지막 anyFalseiterable을 반환 하거나 소진합니다 True.

참고 : 위의 조건은 단일 조건 만 설정되어 있는지 확인합니다.


하나 이상의 항목이 설정되어 있지만 모든 항목이 설정되어 있지 않은지 확인하려면 다음을 사용할 수 있습니다.

not all(conds) and any(conds)


답변

영어 문장 :

“a 또는 b 또는 c 인 경우 모두 해당하지 않는 경우”

이 논리로 변환합니다 :

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

“but”라는 단어는 일반적으로 “and”라는 연결을 의미합니다. 또한, “모두” 는 조건, 즉 이 조건 해당 조건 기타 조건의 조합으로 해석됩니다 . “not”은 전체 연결을 반전시킵니다.

동의 한 답변에 동의하지 않습니다. 저자는 사양에 가장 간단한 해석을 적용하지 않았고 소수의 운영자에게 표현을 단순화하기 위해 De Morgan의 법칙을 적용하지 않았습니다.

 not a or not b or not c  ->  not (a and b and c)

답은 “최소한 형태”라고 주장하면서.


답변

True세 가지 조건 중 하나에 해당 하면를 반환 합니다 True. 아마도 당신이 예제 코드에서 원하는 것입니다.

if sum(1 for x in (a,b,c) if x) == 1:


답변

어떻습니까 : (독특한 조건)

if (bool(a) + bool(b) + bool(c) == 1):

두 조건을 허용하면 그렇게 할 수 있습니다.

if (bool(a) + bool(b) + bool(c) in [1,2]):