if-elif-else 문을 한 줄에 넣습니까?


125

아래 링크를 읽었지만 내 질문을 다루지 않습니다.
파이썬에 삼항 조건 연산자가 있습니까?(문제는 if-else 문을 한 줄로 압축하는 것입니다)

한 줄에 맞도록 if-elif-else 문을 작성하는 더 쉬운 방법이 있습니까?
예를 들면

if expression1:
   statement1
elif expression2:
   statement2
else:
   statement3

또는 실제 예 :

if i > 100:
    x = 2
elif i < 100:
    x = 1
else:
    x = 0

위의 예를 다음과 같이 작성할 수 있다면 더 간결 해 보일 수 있다고 생각합니다.

x=2 if i>100 elif i<100 1 else 0 [WRONG]

답변:


186

아니요, 불가능합니다 (적어도 임의의 진술로는 불가능). 또한 바람직하지도 않습니다. 모든 것을 한 줄에 맞추면 줄 길이가 80자를 넘지 않아야하는 PEP-8을 위반할 가능성이 높습니다 .

또한 Zen of Python : "가독성이 중요합니다"에 위배됩니다. ( import this모든 것을 읽으려면 Python 프롬프트에 입력 하십시오).

Python에서 삼항 표현식을 사용할 있지만 표현식에만 사용할 수 있으며 문에는 사용할 없습니다.

>>> a = "Hello" if foo() else "Goodbye"

편집하다:

수정 된 질문은 이제 할당되는 값을 제외하고 세 문이 동일하다는 것을 보여줍니다. 이 경우 연결 삼항 연산자가 작동하지만 여전히 가독성이 떨어진다고 생각합니다.

>>> i=100
>>> a = 1 if i<100 else 2 if i>100 else 0
>>> a
0
>>> i=101
>>> a = 1 if i<100 else 2 if i>100 else 0
>>> a
2
>>> i=99
>>> a = 1 if i<100 else 2 if i>100 else 0
>>> a
1

두 번째 표현식이 0을 반환하지 않은 이유는 무엇입니까? 나는 100 이상
AstralWolf

6
@AstralWolf : 정말 감사합니다! 이것은 제가 만들려고했던 요점을 완벽하게 보여줍니다. 체인화 된 삼항 표현은 가능하지만 가독성이 떨어지고 분명히 오해하기 쉽습니다.
Tim Pietzcker

1
더 읽기 쉽도록하려면 다음과 같이 괄호를 a = 1 if i < 100 else (2 if i > 100 else 0)묶을 수 있습니다 . (테스트되지 않았지만 작동해야한다고 생각합니다.)
Zac

@TimPietzcker 표현식과 문장의 차이점을 어떻게 설명 하시겠습니까?
AsheKetchum

62

다른 경우에 다른 표현 만 필요하면 다음과 같이 작동 할 수 있습니다.

expr1 if condition1 else expr2 if condition2 else expr

예를 들면 :

a = "neg" if b<0 else "pos" if b>0 else "zero"

1
"pos"진술 이 아니라 표현입니다.
Tim Pietzcker

@TimPietzcker 감사합니다. 게시물을 더 정확하게 업데이트했습니다.
Lycha

20

else 문에 다른 if 절을 중첩하면됩니다. 하지만 그렇다고 더 예쁘게 보이지는 않습니다.

>>> x=5
>>> x if x>0 else ("zero" if x==0 else "invalid value")
5
>>> x = 0
>>> x if x>0 else ("zero" if x==0 else "invalid value")
'zero'
>>> x = -1
>>> x if x>0 else ("zero" if x==0 else "invalid value")
'invalid value'

1
나에게 이것은 첫 번째 절의 구조와 개념을 유지하기 때문에 받아 들여지는 대답보다 훨씬 더 읽기 쉽습니다. 주관적인 문제입니다.
Ezarate11 2011

12

다른 답변에도 불구하고 : 예 가능합니다 .

if expression1:
   statement1
elif expression2:
   statement2
else:
   statement3

다음 하나의 라이너로 변환됩니다.

statement1 if expression1 else (statement2 if expression2 else statement3)

실제로 무한대까지 중첩 할 수 있습니다. 즐겨 ;)


시간은 어때? 제가 생각하기에 이러한 다중 루프는 훨씬 더 많은 시간이 소요될 것입니다. 따라서 더 나은 소비 속도를 위해 중첩 루프에 대한 대안이있을 수 있습니다.
loveR

안녕하세요 @loveR 님, 이것은 루프가 아닙니다. 중첩 된 if else 문이므로 무시할 수있는 시간입니다
gustavz

7

선택적으로 실제로 geta 메서드를 사용할 수 있습니다 dict.

x = {i<100: -1, -10<=i<=10: 0, i>100: 1}.get(True, 2)

get키 중 하나가 다음과 같이 평가되는 경우 메서드 가 필요하지 않습니다 True.

x = {i<0: -1, i==0: 0, i>0: 1}[True]

최대 하나의 키가 이상적으로 평가되어야합니다 True. 둘 이상의 키가로 평가 True되면 결과를 예측할 수없는 것처럼 보일 수 있습니다.



4
if i > 100:
    x = 2
elif i < 100:
    x = 1
else:
    x = 0

위에서 언급 한 코드를 한 줄로 사용하려면 다음을 사용할 수 있습니다.

x = 2 if i > 100 else 1 if i < 100 else 0

이렇게하면 x는 i> 100이면 2, i <100이면 1, i = 100이면 0이 할당됩니다.


3

또한 표현의 성격에 따라 다릅니다. "하지 않음"의 다른 답변에 대한 일반적인 조언은 일반 문과 일반 표현식에 매우 유효합니다.

그러나 주어진 옵션의 값에 따라 다른 함수를 호출하는 것과 같이 "dispatch"테이블 만 있으면 사전에 호출 할 함수를 넣을 수 있습니다.

다음과 같은 것 :

def save(): 
   ...
def edit():
   ...
options = {"save": save, "edit": edit, "remove": lambda : "Not Implemented"}

option = get_input()
result = options[option]()

if-else 대신 :

if option=="save":
    save()
...

2

사람들은 이미 삼항 표현을 언급했습니다. 때로는 간단한 조건부 할당을 예로 들어 수학 식을 사용하여 조건부 할당을 수행 할 수 있습니다. 이것은 당신의 코드를 매우 읽기 쉽게 만들지 못할 수도 있지만 상당히 짧은 줄에 그것을 얻습니다. 귀하의 예는 다음과 같이 작성할 수 있습니다.

x = 2*(i>100) | 1*(i<100)

비교는 True 또는 False가되고 숫자와 곱하면 1 또는 0이됩니다. 하나는 | 대신 +를 사용할 수 있습니다. 중간에.


1

삼항 연산자는 간결한 표현하는 가장 좋은 방법입니다. 구문은 variable = value_1 if condition else value_2입니다. 따라서 예를 들어 삼항 연산자를 두 번 적용해야합니다.

i = 23 # set any value for i
x = 2 if i > 100 else 1 if i < 100 else 0

0

중첩 된 삼항 if 문을 사용할 수 있습니다.

# if-else ternary construct
country_code = 'USA'
is_USA = True if country_code == 'USA' else False
print('is_USA:', is_USA)

# if-elif-else ternary construct
# Create function to avoid repeating code.
def get_age_category_name(age):
    age_category_name = 'Young' if age <= 40 else ('Middle Aged' if age > 40 and age <= 65 else 'Senior')
    return age_category_name

print(get_age_category_name(25))
print(get_age_category_name(50))
print(get_age_category_name(75))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.