3

I'm learning python and I want to make sure I am organizing "if" statements in a correct way. The situation that I keep running a lot into is the following :

if x == 0:
    dostuff_A
    if y == 0:
        dostuff_B            
else:
    dostuff_B

As you can see I keep repeating "dostuff_B" a lot and have to contantly be changing code twice. I know I could have a function instead "dostuff_B" but my question is regarding the if design. Another workaround that I found is doing the following but then i duplicate the if statement.

if x == 0:
    dostuff_A
if x != 0 or y == 0:
    dostuff_B

Any ideas? Thanks in advance!

UPDATE : Removed spaces before colon. Also updated my workaround because didn't make sense. Original version was :

if x == 0:
    dostuff_A
if x == 0 and y == 0:
    dostuff_B
5
  • 7
    The thing here that strikes me as most unpythonic is the space before the : Commented Apr 23, 2013 at 19:45
  • The code makes no sense. Commented Apr 23, 2013 at 19:46
  • 5
    The second if should be if x != 0 or y == 0: Commented Apr 23, 2013 at 19:47
  • No, the second if statement is correct. Per the original code, he only wants to do_stuff_B if X == 0 and Y == 0. Commented Apr 23, 2013 at 19:49
  • Nope. He also want to do stuff_B when x != 0. So user4815162342 is right. Commented Apr 23, 2013 at 19:50

7 Answers 7

6

I see some correct answers have been posted already but they do not explain how they got to the solution.

One way of simplifying nested if-else statements is by using truth tables:

x    y    what you call
-----------------------
0    0    A and B
0    1    A
1    0    B
1    1    B

From the table above you can see that you only call A when x == 0. Let's put that into code:

if x == 0:
    somestuff_A

From the same table you can see that the only time you don't call B is when x == 0 and y == 1. Again, let's put that into code:

if x != 0 or y == 0:
    somestuff_B

or:

if not x == 0 or y == 0:
    somestuff_B

If you put the two pieces of code together this is what you get:

if x == 0:
    somestuff_A
if not x == 0 or y == 0:
    somestuff_B
Sign up to request clarification or add additional context in comments.

1 Comment

not x == 0 always confuses me when I see it. IMO, x != 0 is preferable
4

Considering this initial code:

if x == 0 :
    dostuff_A
    if y == 0 :
        dostuff_B            
else :
    dostuff_B

It can be re-written as:

if x == 0:
    dostuff_A
if x != 0 or y == 0:
    dostuff_B

Comments

4

I don't know if it's more pythonic, but the second style reads more clearly to me (I agree about the space before the colon, and removed it).

if x == 0:
    dostuff_A
if x == 0 and y == 0:
    dostuff_B

This would hold up for other languages as well.

However, the two examples you have (now that I look at it closer) are not logically equivalent; perhaps you meant this:

if x == 0:
    dostuff_A
if x != 0 or y == 0:
    dostuff_B

7 Comments

The issue here is dealing with the case where X != 0, which in the original code block meant destuff_B.
I like your 2nd example. It addresses the issue I raised above.
I don’t like how you had to specify dostuff_B twice. If that’s a longer statement, or multiple lines, it gets very messy and redundant. In this case a simple if x != 0 or y == 0 would work.
Agreed! I'm now assuming he wanted the logic of his first statement, based on the comments
@plalx I also up-voted your answer - not sure the etiquette there!
|
1

Presumably your dostuff_B is actually a larger block of code that should be identical between the branches, and if you change one of the dostuff_B you also need to change the other to keep it consistent. In that case there's a very real danger in duplicating the code and you'd be better off being redundant in the if statement instead.

As pointed out in the comments your second example isn't identical to the first. It should be:

if x == 0:
    dostuff_A
if x != 0 or y == 0:
    dostuff_B

Comments

1

Regardless of your example, which can be easily rewritten to the code below, I’d say it depends on the situation which makes more sense. In any way, I would try to avoid having to specify dostuff_A or dostuff_B more than once. So you are allowed to use more complicated conditions there. On the other hand I would keep the two-level if, if the first dostuff_B would be related to the previous dostuff_A (implying that the second dostuff_B would be something else here). If dostuff_A and dostuff_B are completely unrelated to each other, separating them completely would be preferable.

if x == 0:
    dostuff_A

if x != 0 or y == 0:
    dostuff_B

Comments

1

First, you are correct, your do_stuff should be in two separate functions. Assuming that, I propose the following:

if x == 0 and y == 0:
   do_stuff_A()
   do_stuff_B()
elif x == 0:
   do_stuff_A()
else:
    do_stuff_B()

In my mind, this makes explicitly clear what is happening in the code as I read it:

  • if x and y == 0, then do_stuff_A() and do_stuff_B()
  • if x == 0, then do_stuff_A()
  • In all other cases, just do_stuff_B()

Comments

0

When you write a one-time script, it does not matter much which design is more pythonic - if it is understandable it is good. When you start refactoring it to something more usable, you can use the corresponding refactoring.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.