if 절을 종료하는 방법


104

if절 을 조기에 종료하는 방법에는 어떤 것이 있습니까?

코드를 작성할 때 break문을 if절 안에 넣고 싶을 때가 있는데 , 그것들은 루프에만 사용할 수 있다는 것을 기억하기 위해서입니다.

다음 코드를 예로 들어 보겠습니다.

if some_condition:
   ...
   if condition_a:
       # do something
       # and then exit the outer if block
   ...
   if condition_b:
       # do something
       # and then exit the outer if block
   # more code here

이 작업을 수행하는 한 가지 방법을 생각할 수 있습니다. 종료 사례가 중첩 된 if 문 내에서 발생한다고 가정하고 나머지 코드를 큰 else 블록으로 래핑합니다. 예:

if some_condition:
   ...
   if condition_a:
       # do something
       # and then exit the outer if block
   else:
       ...
       if condition_b:
           # do something
           # and then exit the outer if block
       else:
           # more code here

이 문제는 더 많은 종료 위치가 더 많은 중첩 / 들여 쓰기 코드를 의미한다는 것입니다.

또는 if절을 가능한 한 작게 만들고 종료가 필요하지 않도록 코드를 작성할 수 있습니다.

if절 을 종료하는 좋은 / 더 나은 방법을 아는 사람이 있습니까?

연관된 else-if 및 else 절이 있으면 종료하면 해당 절을 건너 뛸 수 있습니다.


2
두 번째 코드 샘플에 대해 알고 elif있습니까?
— Craig McQueen

2
"또는 if 절이 가능한 한 작고 종료가 필요하지 않도록 코드를 작성할 수 있습니다." -그리고 확실히 이것이 최선의 조치가 될 것입니다. :-)
— Michał Marczyk

2
@Craig McQueen : 그렇습니다.하지만 조건문 사이에서 코드를 실행하고 싶다고 말합니까? 예를 들어 if a: #stuff; #stuff_inbetween; if b: #stuff;inbetween 코드는에 의존 not a하지만 의존하지 않습니다 b.
— Roman

안녕하세요 잊지 마세요 elif stackoverflow.com/a/2069680/7045119
— kerbrose

답변:


99

(이 방법은 ifs, 다중 중첩 루프 및 break쉽게 얻을 수없는 기타 구문에 대해 작동합니다 .)

자체 함수로 코드를 래핑합니다. 대신 break, 사용 return.

예:

def some_function():
    if condition_a:
        # do something and return early
        ...
        return
    ...
    if condition_b:
        # do something else and return early
        ...
        return
    ...
    return

if outer_condition:
    ...
    some_function()
    ...

4
프로그래머 트릭 가방에 추가하게되어 기쁩니다. 제 경험상, 이러한 접근 방식은 전진하는 고토를 사용하고 싶을 때 거의 항상 효과가 있습니다. (그리고에서 그것을 모두 힌트를 하나의 함수가 너무 큰지고 주소 상황)
— 드류 Dormann에게

2
이상적으로는 둘 다 달성 할 수 있지만 좋은 성능을 위해 좋은 코드를 교환해야하는 경우가 있습니다. 특히 Python 사용을 고려할 때 이러한 경우는 드뭅니다. 즉, 함수 호출 오버 헤드에 대해 그다지 걱정하지 마십시오.
— ephemient

17
오래된 일화가 있습니다. "Dennis Ritchie는 함수 호출이 C에서 정말, 정말 저렴하다고 말함으로써 모듈화를 장려했습니다. 모두가 작은 함수를 작성하고 모듈화하기 시작했습니다. 몇 년 후 우리는 PDP-11에서 함수 호출이 여전히 비싸다는 것을 알게되었습니다. , VAX 코드는 종종 CALLS 명령에 시간의 50 %를 소비했습니다. Dennis는 우리에게 거짓말을했습니다.하지만 너무 늦었습니다. 우리는 모두 푹 빠져있었습니다 ... "
— ephemient

1
@ephemient : 재밌 네요, 이야기에 더 많은 것이 있나요? 모든 것을 읽고 싶습니다.
— Roman

4
이 인용문은 The Art of Unix Programming ( faqs.org/docs/artu 에서 온라인) 책의 4 장에서 발췌 한 것 입니다. 전에 읽지 않았다면 모든 것을 읽어야합니다.
— ephemient

55
에서 고토 수입 고토, 라벨

some_condition :
   ...
   condition_a 인 경우 :
       # 뭔가를
       # 그런 다음 외부 if 블록을 종료합니다.
       goto .end
   ...
   condition_b 인 경우 :
       # 뭔가를
       # 그런 다음 외부 if 블록을 종료합니다.
       goto .end
   # 여기에 더 많은 코드

label .end

(실제로 사용하지 마세요.)


35
이것은 재미 있기 때문에 +1. 구글 검색 결과 이것이 만우절의 농담 모듈이라는 것을 알게되었습니다.
— Roman

2
나도 연결했습니다. 첫 번째를 클릭하십시오 goto.
— ephemient

1
이 :) 분기의 모든 종류의 어셈블리 코드를 생각 나게
— phunehehe

2
@ephemient : 아, 링크를 보지 못했습니다. 코드 하이라이트라고 생각했습니다. 하지만 이제 여러분의 코드를 살펴 보니 실제 하이라이트가 표시되지 않습니다.
— Roman

1
PHP가 goto를 도입했을 때 저는 Python php.net/manual/en/control-structures.goto.php를 사용했습니다.
— Marc

25
while some_condition:
   ...
   if condition_a:
       # do something
       break
   ...
   if condition_b:
       # do something
       break
   # more code here
   break

3
오,이 아이디어가 정말 마음에 들어요. 이것이 내 원래의 욕망을 정확히 해결했다고 생각합니다. 그러나 나는 이것이 좋은 습관이 아니라는 잔소리를 느낍니다 (그리고 그 이유 때문에 좋은 코딩 스타일을 장려하기 때문에 지금은 현재 받아 들여지는 대답을 유지할 것입니다).
— Roman

6
원본을 유지하고 전체를 while True:. 단지에 넣어해야합니다 break말에 문! do-while 구조를 사용하는 언어의 경우 다음을 수행하는 것이 더 do { code that can conditionally break out } while (false);
— 우상적입니다

10

예외를 제외하고 goto의 기능을 에뮬레이션 할 수 있습니다.

try:
    # blah, blah ...
    # raise MyFunkyException as soon as you want out
except MyFunkyException:
    pass

면책 조항 : 나는 이러한 방식으로 일을 할 수 있는 가능성 을 귀하에게 알리려는 의미 일 뿐이며 , 정상적인 상황에서 합리적이라고 보증하지는 않습니다. 질문에 대한 의견에서 언급했듯이, 처음부터 비잔틴 조건문을 피하기 위해 코드를 구조화하는 것이 훨씬 바람직합니다. :-)


하하,이 창의적인 솔루션이 마음에 듭니다. 나는 귀하의 면책 조항을 준수하고 그러한 펑키 코드를 사용하지 않을 것입니다.
— Roman

@Roman : Shmoopty와 함께 또 다른 트릭을 추가하게되어 기쁩니다. ;-)
— Michał Marczyk

8

이럴까요?

if some_condition and condition_a:
       # do something
elif some_condition and condition_b:
           # do something
           # and then exit the outer if block
elif some_condition and not condition_b:
           # more code here
else:
     #blah
if

1
그래, 작동 할 수있다. elif이 글을 쓰는 동안 내 마음이 텅 빈 것 같아요 . 중첩 된 if 문 사이에서 코드를 실행하려는 상황에서는 이것이 작동하지 않을 것이라고 생각합니다.
— Roman

이것은 실제로 정답입니다. 사람들이 이것을 추천하지 않는 이유는 무엇입니까 ?? :)
— kerbrose

6

실제로 요청한 것에 대해 제 접근 방식은 if s를 단일 루프 루프

while (True):
    if (some_condition):
        ...
        if (condition_a):
            # do something
            # and then exit the outer if block
            break
        ...
        if (condition_b):
            # do something
            # and then exit the outer if block
            break
        # more code here
    # make sure it is looped once
    break

테스트 :

conditions = [True,False]
some_condition = True

for condition_a in conditions:
    for condition_b in conditions:
        print("\n")
        print("with condition_a", condition_a)
        print("with condition_b", condition_b)
        while (True):
            if (some_condition):
                print("checkpoint 1")
                if (condition_a):
                    # do something
                    # and then exit the outer if block
                    print("checkpoint 2")
                    break
                print ("checkpoint 3")
                if (condition_b):
                    # do something
                    # and then exit the outer if block
                    print("checkpoint 4")
                    break
                print ("checkpoint 5")
                # more code here
            # make sure it is looped once
            break

1
솔직히 이것은 가장 깨끗한 솔루션입니다. 코드가 언제 종료되는지는 매우 분명합니다. 함수 내부의 함수 범위 지정에 대해 걱정할 필요가 없으며 성능이나 논리적 부채가 없습니다.
— Trent

2
for _ in range(1):대신을 사용하는 것이 좋습니다 while True:. (1) 단일 반복 루프의 의도를 더 잘 전달하고 (2) 루프를 종료하기위한 마지막 break 문이 없습니다 (나중에 실수로 제거 될 수 있음)
— Bernhard Kausler

3

일반적으로 말하지 마십시오. 만약 당신이 "ifs"를 중첩하고 그로부터 분리한다면, 당신은 잘못하고있는 것입니다.

그러나 다음을 수행해야하는 경우 :

if condition_a:
   def condition_a_fun():
       do_stuff()
       if we_wanna_escape:
           return
   condition_a_fun()
if condition_b:
   def condition_b_fun():
       do_more_stuff()
       if we_wanna_get_out_again:
           return
   condition_b_fun()

함수는 if 문에서 선언 할 필요가 없습니다. 미리 선언 할 수 있습니다.


답변 해주셔서 감사합니다. '중첩 루프'가 무엇을 의미하는지 잘 모르겠습니다. 'break'라는 키워드에 대한 언급을하신다면, 저는 루프 이탈의 존재와 비교하여 if-exit에 대한 검색에 동기를 부여하려고했습니다. 내 예를했던대로 코드가 문제를 해결하는 방법 또한, 나는 확실하지 오전 if condition_a과 if condition_b내부 중첩 if some_condition. 나는 if some_condition.
— Roman

사람들이 if를 중첩하고 깨뜨리고 싶어하는 이유는 아마도 그들이 잘못하고 있기 때문이 아니라 깔끔하고 단순하고 DRY 코드를 작성하기를 원하기 때문일 것입니다. 간단한 경우는 condition_a와 condition_b가 모두 충족 될 때 프로그램이 x ()를 수행해야하고 condition_a에 대해서만 y ()를 수행해야하고 condition_b에 대해서만 z ()를 수행해야하는 경우입니다. 그리고 코더는 x () 쓰기를 여러 번 거부합니다
— izzulmakin

1

효과적으로 설명하는 것은 goto 문이며 일반적으로 상당히 많이 패닝됩니다. 두 번째 예는 이해하기 훨씬 쉽습니다.

그러나 클리너는 여전히 다음과 같습니다.

if some_condition:
   ...
   if condition_a:
       your_function1()
   else:
       your_function2()

...

def your_function2():
   if condition_b:
       # do something
       # and then exit the outer if block
   else:
       # more code here

1

함수 정의에 의존하지 않고 (때로는 작은 코드 스 니펫에서는 가독성이 떨어지기 때문에), 추가 외부 while 루프를 사용하지 않는 또 다른 방법이 있습니다 (첫눈에 이해하기 위해 주석에 특별한 감사가 필요할 수 있음). , goto (...)를 사용하지 않으며 가장 중요한 것은 중첩 항목을 시작할 필요가없는 경우 바깥쪽에 대한 들여 쓰기 수준을 유지하는 것입니다.

if some_condition:
   ...
   if condition_a:
       # do something
       exit_if=True # and then exit the outer if block
if some condition and not exit_if: # if and only if exit_if wasn't set we want to execute the following code
   # keep doing something
   if condition_b:
       # do something
       exit_if=True # and then exit the outer if block
if some condition and not exit_if:
   # keep doing something

예, 가독성을 위해 두 번째 검토가 필요하지만 코드 조각이 작 으면 반복되지 않는 while 루프를 추적 할 필요가 없으며 중간 if가 무엇인지 이해 한 후 쉽게 읽을 수 있습니다. 같은 들여 쓰기로 한 곳.

그리고 꽤 효율적이어야합니다.


0

그래서 나는 당신이 외부 if 코드 블록 에서 벗어나려고한다는 것을 이해합니다.

if some_condition:
    ...
    if condition_a:
       # do something
       # and then exit the outer if block
       ...
    if condition_b:
       # do something
       # and then exit the outer if block
# more code here

한 가지 방법은 외부 if 블록에서 거짓 조건을 테스트 할 수 있다는 것입니다. 그러면 코드 블록에서 묵시적으로 종료되고 else 블록을 사용하여 다른 if를 중첩하여 작업 을 수행 할 수 있습니다.

if test_for_false:
    # Exit the code(which is the outer if code)

else:
    if condition_a:
        # Do something

    if condition_b:
        # Do something

0

추가 방법없이이를 적용 할 수있는 유일한 방법은 elif다음과 같습니다.

a = ['yearly', 'monthly', 'quartly', 'semiannual', 'monthly', 'quartly', 'semiannual', 'yearly']
# start the condition
if 'monthly' in b: 
    print('monthly') 
elif 'quartly' in b: 
    print('quartly') 
elif 'semiannual' in b: 
    print('semiannual') 
elif 'yearly' in b: 
    print('yearly') 
else: 
    print('final') 

-1

이를 처리하는 또 다른 방법이 있습니다. 계속 사용하는 단일 항목 for 루프를 사용합니다. 이유없이 추가 기능을 가질 필요가 없습니다. 또한 잠재적 인 무한 while 루프를 제거합니다.

if something:
    for _ in [0]:
        # Get x
        if not x:
            continue

        # Get y
        if not y:
            continue

        # Get z
        if not z:
            continue

        # Stuff that depends on x, y, and z

-2

사용 return하여 함수의 조건 의지 반환 당신을, 그래서 당신이 사용할 수있는 경우 대가는은 if 조건을 깰.


2
그는 기능을 종료하지 않으면 중단하길 원합니다
— StealthOne
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.