Reputation: 403
I was working through a problem where I was reversing words in place. I noticed that depending on the order of my statements before and after my or
operator, the code would not work or work.
If I change
if i == len(s1) or s1[i] == ' ':
to
if s1[i] == ' ' or i == len(s1):
I get the error
Traceback (most recent call last):
File "reverse_words_in_place.py", line 58, in <module>
reverse_words(s1)
File "reverse_words_in_place.py", line 6, in reverse_words
if s1[i] == ' ' or i == len(s1):
IndexError: list index out of range
def reverse_words(s1):
reverse_string(s1, 0, len(s1)-1)
start_index = 0
for i in range(len(s1)+1):
if i == len(s1) or s1[i] == ' ':
reverse_string(s1, start_index, i-1)
start_index = i + 1
return s1
def reverse_string(s1, first, last):
while(first < last):
s1[first], s1[last] = s1[last], s1[first]
first += 1
last -= 1
s1 = ['c', 'a', 'k', 'e', ' ',
'p', 'o', 'u', 'n', 'd', ' ',
's', 't', 'e', 'a', 'l']
reverse_words(s1)
# Prints: 'steal pound cake'
print(''.join(s1))
The output for this code is
steal pound cake
as long as
if i == len(s1) or s1[i] == ' ':
Why does it matter in what order these statements are?
Upvotes: 1
Views: 1343
Reputation: 656
This is because in python, as in most programming languages, the operators or and and short circuit. For example, if the left hand side of or is true, then it knows the entire or statement will be true without bothering to check the right hand side.
Long winded explanation:
It may seem like to evaluate A or B we would start by evaluating A, then we'd evaluate B and finally the results would be or'd together for the final result. However, what actually happens is the "short circuit": A is evaluated and, if it is true, we don't bother evaluating B AT ALL because we know right then and there that A or B evaluates to true.
Similarly, A and B short circuits: we start by evaluating A and if it is false we already know that A and B will evaluate to false, so we don't bother evaluating B at all.
This can actually be used to write more succinct code. For example, the following:
if A: # is obj valid?
if B: # do a check that requires obj to be valid
C
...could be written like this instead:
if A and B:
C
Upvotes: 4
Reputation: 8510
Because if i == len(s1)
is true
the second statement is not evaluated and you don't get IndexError
.
The reason for it is Short-circuit_evaluation.
Upvotes: 8