7. Looping and Counting

If you want to find out if a particular character is in a string, you could iterate through the string and compare each character to the desired character and then return a boolean value indicating if it was found or not.

But you could also just use the convenient in operator (or its opposite, not in) and it will return the same information. The in operator tests if one string is a substring of another:

Note that a string is a substring of itself, and the empty string is a substring of any other string. (Also note that computer scientists like to think about these edge cases quite carefully!)

The not in operator returns the logical opposite result of in.

The Accumulator Pattern with Strings

Let’s work through a more complex string looping example. Combining the in operator with string concatenation using + and the accumulator pattern, we can write a function that removes all the vowels from a string and returns a new string consisting of only the non-vowel characters.

The idea is to start with a string and iterate over each character, checking to see if the character is a vowel. As we process the characters, we will build up a new string consisting of only the non-vowel characters. To do this, we use the accumulator pattern which allows us to keep a “running total”. But in this case we are not accumulating a numeric total. Instead we are accumulating the non-vowel characters onto a string.

Line 5 uses the not in operator to check whether the current character is not in the string vowels. Look carefully at line 6 in the above program (no_vowels = no_vowels + each_char). We will do this for every character that is not a vowel. This should look very familiar. As we were describing earlier, it is an example of the accumulator pattern, this time using a string to “accumulate” the final result. In other words it says that the new value of no_vowels will be the old value of no_vowels concatenated with the value of each_char. Thus, we are building the result string character by character.

Take a close look also at the initialization of no_vowels. We start with an empty string and then begin adding new characters to the end. Otherwise we would get an error at line 6 if we tried to use the variable before initializing it.

Step through the function using codelens to see the accumulator variable grow.

(ch08_acc2)

Let’s look at another example of the accumulator pattern, but this one does calculate a numeric value. The following program counts the number of times a particular letter, char, appears in a string.

The function count takes a string as its parameter. The for statement iterates through each character in the string and checks to see if the character is equal to the value of char. If so, the counting variable, letter_count, is incremented by one. When all characters have been processed, the letter_count is returned. (Note that str does have a count method that you can use to perform the same task.)

Check your understanding

    What is printed by the following statements:

    s = "ball"
    r = ""
    for item in s:
        r = item.upper() + r
    print(r)
    
  • Ball
  • Each item is converted to upper case before concatenation.
  • BALL
  • Each character is converted to upper case but the order is wrong.
  • LLAB
  • Yes, the order is reversed due to the order of the concatenation.