1

Let's say I'm iterating through a list of input that can be keys in one of two dictionaries.

  for key in inputs:
      if key in status_msg.keys():
          print status_msg[key]
      elif key in error_msg.keys():
          print error_msg[key]

Now I was reading about the continue command here and here and I was wondering if this would be a better way of doing it:

  for key in inputs:
      if key in status_msg.keys():
          print status_msg[keys]
          continue
      if key in error_msg.keys():
          print error_msg[key]

Would there be any benefits from using continue instead of if elif or is it exactly the same?

Community
  • 1
  • 1
plover
  • 439
  • 5
  • 17
  • No, you have simply added another line. The loop would have continued at that point anyway. – 2rs2ts Mar 20 '14 at 17:23
  • It does the same thing and is slightly longer, so I would say no benefits here! – jonrsharpe Mar 20 '14 at 17:23
  • What is the intended benefit of not using `elif`? In the minimal use case presented `elif` is simple and `continue` is a little less so. It would be okay to use `continue` instead for some purposes, but, if you want to do that, what is the reason why? – aestrivex Mar 20 '14 at 17:27

4 Answers4

5

If you forget a continue, it'll be harder to notice and correct the bug than if you accidentally use if instead of elif. The ifs and elifs stick out from the indented blocks they contain, making them easier to notice. Also, if you add a new block, it's easy to forget to put a continue on the end of the last one. The problems with using continue for this are essentially the same as the problems with the C switch statement, and generations of C programmers can tell you horror stories about forgetting to break out of switches.

Performancewise, there is unlikely to be any measurable difference. As the two code snippets are equivalent, the difference will come down to implementation details of the bytecode compiler and the jump instructions it produces.

A much more significant improvement will come from replacing tests like

if key in status_msg.keys():

with

if key in status_msg:

Testing whether something is in a dict's keys requires creating a list of keys and then going through them one by one. Testing whether the thing is in the dict directly is a quick hash lookup.

user2357112
  • 260,549
  • 28
  • 431
  • 505
5

The control flow would be the same in your specific example. If the code remained unchanged, there'd be no difference. It might even compile down to the same byte-code.

The elif version states your intent more clearly, however. You're telling whomever reads the code that you expect to find key in status_msg, and if it's not there, you expect to find it in error_msg. To me it appears that other parts of your code will only populate error_msg when status_msg is not populated.

The continue version leaves things more ambiguous. Is error_msg populated in every case? The continue version is also less future-proof: what if you want to do something else after printing, regardless of where key is found? If you consider this code:

for key in inputs:
    if key in status_msg.keys():
        print status_msg[keys]
        continue
    if key in error_msg.keys():
        print error_msg[key]
    do_something()

Then do_something() is only executed when key is not in status_msg. The conditionals are asymmetrical; one aborts the iteration and the other lets control flow out to the rest of the block. That might not be obvious to someone approaching the code later, especially if the conditionals contain more complex logic/more lines.

I think the elif version is superior: it's future-proof, states your intent, and is symmetrical. The performance is probably identical, and even if it's not, it's nominally different and irrelevant.

Jim Stewart
  • 16,964
  • 5
  • 69
  • 89
1

In the example you gave, while it is to some extent a matter of preference, I would prefer if / elif as I believe it more clearly expresses the logic that you want to print one of the two values.

continue is better suited to larger loops in which certain instances of the loop should be skipped entirely (but those instances are too complex to clearly program into the range or list comprehension used to control the loop) or certain instances of the loop require substantially less processing and therefore should exit early.

The problem in the example you give is that if you later add more general-purpose code at the end of the loop, it may not be immediately obvious that the code will not be executed when key is in status_msgs.

Larry Lustig
  • 49,320
  • 14
  • 110
  • 160
0

Same thing. If there are any performance differences, you may be able to profile it with enough looping or sample data for your comparison.

user176692
  • 780
  • 1
  • 6
  • 21