22.4: Looping with Indices
- Page ID
- 15407
I wrote the functions in the previous section with for
loops because I only needed the characters in the strings; I didn’t have to do anything with the indices.
For is_abecedarian
we have to compare adjacent letters, which is a little tricky with a for
loop:
def is_abecedarian(word): previous = word[0] for c in word: if c < previous: return False previous = c return True
An alternative is to use recursion:
def is_abecedarian(word): if len(word) <= 1: return True if word[0] > word[1]: return False return is_abecedarian(word[1:])
Another option is to use a while
loop:
def is_abecedarian(word): i = 0 while i < len(word)-1: if word[i+1] < word[i]: return False i = i+1 return True
The loop starts at i=0
and ends when i=len(word)-1
. Each time through the loop, it compares the ith character (which you can think of as the current character) to the i+1th character (which you can think of as the next).
If the next character is less than (alphabetically before) the current one, then we have discovered a break in the abecedarian trend, and we return False
.
If we get to the end of the loop without finding a fault, then the word passes the test. To convince yourself that the loop ends correctly, consider an example like 'flossy'
. The length of the word is 6, so the last time the loop runs is when i
is 4, which is the index of the second-to-last character. On the last iteration, it compares the second-to-last character to the last, which is what we want.
Here is a version of is_palindrome
(see Exercise 6) that uses two indices; one starts at the beginning and goes up; the other starts at the end and goes down.
def is_palindrome(word): i = 0 j = len(word)-1 while i<j: if word[i] != word[j]: return False i = i+1 j = j-1 return True
Or, if you noticed that this is an instance of a previously-solved problem, you might have written:
def is_palindrome(word): return is_reverse(word, word)
Assuming you did Exercise 8.11.1.