Continue to elif after a nested if-statement?

冷暖自知 提交于 2020-01-25 20:20:15

问题


If the nested if-statement doesn't fulfill a condition, how do I continue on to the outer if? Eg. I have this (very impractical) example:

a = 2

if( a > 1 ):
    if( a == 3 ):
        print "yes"
elif( a == 2 ):
    print "yes"

I want a == 2 to be checked next. How would I do this?

(I have multiple conditions in that nested if that I need to check so I'd rather not have a huge string of and/or statements in that one outer-if. I also have more than one elif statement so I don't want to mash all the elifs together under that nested one.)

A deeper example:

b = 8

if( a > 1 ):
    if( b == 3 ):
        doSomething()
    elif( b == 4 ):
        doSomethingElse()
    elif( b == 5 ):
        more()
elif( -1 <= a <= 1 ):
    asd()
elif( a < -1 ):
    if( b == 7 ):
        asdfasdf()
    elif( b == 8 ):
        asasdf()

回答1:


How do you expect this to be clear to a computer?

if a > 1:
  # ANYTHING
elif a == 2:
  # ANYTHING

by definition will never execute anything in the second block.

I believe your intend might be more along this lines:

def action():
  if a > 1:
    if b == 2:
      doSomething()
      return
    if b == 3:
      doSomethingElse()
      return
 if a == 2: # Note: NO elif!
   doDefaultForA2()
   return
 showError("Unknown command")
 return

There are multiple ways to achieve this behaviour. I like the function+return pattern, because it structures code nicely. Another way is to use a handled flag:

unhandled = True
if a > 1:
  if b == 2:
    doSomething()
    unhandled = False
  if unhandled and b == 3:
    doSomethingElse()
    unhandled = False
if unhandled and a == 2: # Note: NO elif!
  doDefaultForA2()
  unhandled = False
if unhandled:
  showError("Unknown command")

(You can obviously put in a number of shortcuts here by using elif. But using explicit "if unhandled" makes the code more verbose about the logic and easier to add new options.)




回答2:


combine the conditions and flatten the nesting:

a = 2

if ( a > 1 and a == 3 ):
    print "yes"
elif ( a == 2 ):
    print "yes"



回答3:


Considering the example is just indicative but your original question was to understand nested if-else, association, scoping ....

In Python, unlike Algol-like languages we don't have demarcated blocks (for ex. in C we use '{' to make a block. Here all blocks are via proper white-space indentation. Its like the philosophy, what you read is what you would get. This off-course is to adhere to the design philosophy "Code Readability".

In similar context, whether the subsequent if/else statement would be part of the outer or inner if statement depends on how it was indented.

Your example

a = 2

if( a > 1 ):
    if( a == 3 ):
        print "yes"
elif( a == 2 ):
    print "yes"

Here elif is part of the outer if, because that's what it reads or rather looks and that's how it was indented. Instead the below modified version of your code

a = 2

if( a > 1 ):
    if( a == 3 ):
        print "yes"
    elif( a == 2 ):
        print "yes"

Would make the logic apparently different. More because the indented elif block is now aligned with the inner if.

This is now much easier compared to the following C Code

if (a > 1) 
   if (a == 3)
      printf("Hello World\n");
else if (a == 2)
   printf("Yes");

Can you easily say with which if the else if is associated?




回答4:


a = 2
if a > 1:
    if a == 3:
        print "a is 3"
    elif a == 2:
        print "a is 2"



回答5:


What outcomes do you want:

  • print "yes" when a is 2 or 3
  • otherwise do nothing

Translate that into simple code

if a in (2, 3):
    print "yes"

"deeper" example: You don't need some of your nesting. The following simple code is equivalent to yours:

if a == 1:
    if b == 7:
        print "yes 1, 7"
    elif b == 8:
        print "yes 1, 8"
elif a == 2:
    print "yes 2"
elif a == 3:
    print "yes 3"
elif a == 4:
    print "yes 4"
elif a == 5:
    print "yes 5"

By the way, please read PEP 8 and have a look at some of the code written by others... if( foo == 9 ): is an unfamiliar pattern which causes readers to slow down over the speed humps, and possibly avoid that road in future.




回答6:


Another way of writing this to make it easier to read and possibly easier to write would be to put the choices for one of the checks into a dictionary. This will only work if you actually are checking equality, but may work for you.

#used when a>1
bchoices1 = {}
bchoices1[3] = doSomething
bchoices1[4] = doSomethingElse
bchoices1[5] = more

#used when a==1
bchoices2 = {}
bchoices2[7] = asdfasdf
bchoices2[8] = asdfas

if( a > 1 ):
    bchoices1[b]()
elif( a == 2 ):
    asd()
elif( a == 1 ):
    bchoices2[b]()


来源:https://stackoverflow.com/questions/8365714/continue-to-elif-after-a-nested-if-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!