Traversal by Character
for ch in word: — the form to reach for unless you have a reason not to. The loop variable holds the character itself, so there is nothing to look up and nothing to get out of range. Nearly every string program you will be set is one of the three shapes on this page.
1Three shapes, and that is most of it
Every program here starts a variable above the loop and does something to it inside — the collector idea from the for loop practice, with characters instead of numbers. What changes is only what the collector is:
count = 0A number that goes up when the character passes a test.
total = 0A number that adds something worked out from the character.
result = ''A string that grows by one character at a time.
2Program 1 — count the capital letters
Count how many capital letters a sentence contains.
# count the capital letters in a sentence
sentence = 'Learn Python With LambdaLab'
count = 0
for ch in sentence:
if ch.isupper():
count = count + 1
print('Capital letters:', count)Capital letters: 5
for ch in sentence:One round per character — every character, spaces included. The name ch is not special; letter or c would do exactly the same. It is called the loop variable and it is created by this line.
if ch.isupper():ch is a one-character string, so every string method works on it. isupper() answers True or False, which is all an if needs.
count = count + 1Eight spaces: inside the if, inside the loop. Pull it back to four and every character is counted, capital or not.
ch is a string, so it has all the string methods. ch.isupper(), ch.isdigit(), ch.lower(), even ch in 'aeiou' — a one-character string is not a special kind of value, it is just a short string.3Program 2 — add up the digits inside a string
A string holds letters and digits mixed together. Add up the digits.
# add up the digits that appear inside a string
data = 'a1b2c3d4'
total = 0
for ch in data:
if ch.isdigit():
total = total + int(ch)
print('The digits add up to', total)The digits add up to 10
int(ch) is doing real work here. ch is the text '1', not the number 1. Leave int() out and Python raises TypeError: unsupported operand type(s) for +: 'int' and 'str' — the same trap as the missing int() around input(), in a new place.4Program 3 — keep only the digits
A phone number has been typed with spaces and dashes in it. Produce the digits on their own.
# keep only the digits of a phone number
messy = 'Ph: 98-765-43210'
digits_only = ''
for ch in messy:
if ch.isdigit():
digits_only = digits_only + ch
print('Digits only:', digits_only)Digits only: 9876543210
The collector starts as '' — the empty string, which is to joining what 0 is to adding. Each round either adds one character or does not, and after the last round the answer is complete. A string is never edited in place: each + builds a new string and the name is pointed at it.
5The mistake everybody makes: changing ch
This program looks like it upper-cases a word. It does nothing at all:
# changing the loop variable does not change the string
word = 'cat'
for ch in word:
ch = ch.upper()
print(word)cat
ch is a box of its own, refilled each round. It is handed the next character; it is not the character's place inside the string. Writing to it points that box somewhere new and the string never hears about it. Two lessons meet here: strings are immutable, so nothing can change one in place, and upper() returns a new value rather than editing anything.The way to “change” a string is the way program 3 does it — build a new one and give it a name:
# the way to do what that program was trying to do
word = 'cat'
shouting = ''
for ch in word:
shouting = shouting + ch.upper()
print(word)
print(shouting)cat CAT
Both lines are worth reading: word is still cat. Nothing that has happened could have changed it.
6Program 4 — the longest run of one letter
How many times in a row does the most-repeated letter appear? In aabbbccddddde the answer is 5.
# how long is the longest run of the same letter?
word = 'aabbbccddddde'
best = 1
run = 1
for i in range(1, len(word)):
if word[i] == word[i - 1]:
run = run + 1
else:
run = 1
if run > best:
best = run
print('The longest run is', best, 'characters')The longest run is 5 characters
for ch in word. It has to compare each character with the one before it, and a loop variable holding a character cannot look backwards. That is the signal to switch forms — which is the next page. Note also that the loop starts at 1, not 0: there is no character before the first one.7Recap
So every string method works on it, and so does in. It is not a special character type — Python has none.
count = 0, total = 0 or result = '' before the loop; the print at the margin once the loop is done.
The loop variable is a box that is refilled each round, not the character's place in the string. Build a new string instead.
No position means no word[i + 1] and no word[i - 1]. The moment a problem needs those, switch to the index form.
- 1
Count the spaces in a sentence.
Hint · The test is
ch == ' '— a space in quotes is a perfectly ordinary character. - 2
Count how many characters are not letters.
Hint ·
not ch.isalpha(), and remember a space is not a letter. - 3
Build a new string with every vowel turned into a star.
Hint · An
if…elseinside the loop: add'*'in one branch andchin the other. - 4
Add up the lengths of nothing — count the characters without
len().Hint · A counter that goes up once per round, with no
ifat all. - 5
Print the vowels of a word on one line, separated by spaces.
Hint · Build the line as a string with
+ ch + ' 'and print it once, after the loop.
word = 'cat'; for ch in word: ch = ch.upper(). What does print(word) show afterwards?
Why does total = total + ch fail when ch is a digit character?