2

This question could be asked in a language independent way but I'm asking in the context of python since different languages will have different nuances.

I recognize that this is similar to this question but I think mine is different in that I'm asking about a case where putting the two conditions in the same if statement with & will generate an error.

Let's say I want to see if abc[x] is equal to 'fish' but let's say I don't know for sure that len(abc) is >= to x. I can't just have if abc[x]=='fish' because it might be index out of range. As such I need to do

if len(abc)>x:
    if abc[x]=='fish':
        dostuff
    else:
        dootherstuff
else:
    dootherstuff

Is there a cleaner way to do this where I don't have two else statements that end up doing the same dootherstuff? If I want to change what dootherstuff is later than I have to change it in both places but by then I might forget. Sure I could try to comment the code to remind myself later or make dootherstuff a function but that still seems second best. A lot of times when I wind up doing this the dootherstuff is just a one line of code so making it a function doesn't feel much better even though it addresses the subsequent change scenario.

Community
  • 1
  • 1
Dean MacGregor
  • 11,847
  • 9
  • 34
  • 72
  • What about a try-except? Generally faster too, if length will be within bounds most of the time. – xrisk Jun 22 '15 at 23:14
  • [`and`](https://en.wikipedia.org/wiki/Short-circuit_evaluation) is a short-circuit operator in Python - it sounds ideal for your purpose. Alternate suggestion: try "if all()": `if all([condition1, condition2])` – paulsm4 Jun 22 '15 at 23:15
  • wrapping around try-except just replaces the outer if-else and I still end up do `dootherstuff` twice. – Dean MacGregor Jun 23 '15 at 01:11

2 Answers2

4

Sure, here it is:

if len(abc) > x and abc[x] == 'fish':
    dostuff
else:
    dootherstuff

and short-circuits, so abc[x] == 'fish' will only be evaluated if len(abc) > x is True. Most languages have a similar operator (e.g. && in C).

& is for bitwise "and," and doesn't short-circuit, so don't use that.

DOOManiac
  • 6,066
  • 8
  • 44
  • 67
kindall
  • 178,883
  • 35
  • 278
  • 309
  • @kindall, if `x` happens to be exactly `len(abc)`, wouldn't this still cause an index out of range exception when `abc[x] == 'fish'` is checked, since `len(abc) >= x` evaluates to true? – Alejandro Jun 22 '15 at 23:26
  • Yeah, but it's the same problem as the original. – kindall Jun 22 '15 at 23:33
  • I didn't realize this worked. I know that doesn't work in VBA but I guess it's my fault for assuming VBA's faults onto other languages. – Dean MacGregor Jun 23 '15 at 01:09
  • @Alejandro good point, I'm used to R where lists and vectors start at 1 instead of 0. It's a simple fix to change the `>=` to just `>` though – Dean MacGregor Jun 23 '15 at 01:13
  • @DeanMacGregor: Yeah, assuming any other language works like VBA is gonna send you off into the weeds. :-) – kindall Jun 23 '15 at 17:14
2

You could definitely combine both conditions with a logical and operator. Most, if not all, modern programming languages employ short circuit evaluation, including Python. I.e., the process the expression step by step, and do not evaluate parts of it they do not need. Here, if the left side of an and expression is False, the whole thing will be False, and there's no need to evaluate the righthand side, so, something like this would be completely safe:

if len(abc)>=x and abc[x]=='fish':
    dostuff
else:
    dootherstuff
Mureinik
  • 297,002
  • 52
  • 306
  • 350