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