Working Word by Word
Everything so far has walked a sentence one character at a time. Half the questions you will be set are about its words, and there is one line that changes the unit: sentence.split() hands back a list of words, and a for loop over a list works exactly as it does over a string.
1One line changes what the loop walks
# the same sentence, two different units
sentence = 'learn python at lambdalab'
print(sentence.split())
print(len(sentence), 'characters')
print(len(sentence.split()), 'words')['learn', 'python', 'at', 'lambdalab'] 25 characters 4 words
split() gives a list, and each item is a whole word. So for w in sentence.split(): hands out 'learn', then 'python' — each one an ordinary string you can measure with len(), index with w[0] and test with w.isupper(). The spaces are gone: they were the dividers, and they are not part of any word.Called with nothing, split() splits on runs of whitespace — one space or five, a tab or a newline — and throws away the empty pieces. That is why it counts the words of a badly typed sentence correctly when a hand-written space-counter does not.
2Program 1 — count the words and measure each
Ask for a sentence, say how many words it has, and print each word with its length.
# how many words, and how long is each?
sentence = input('Enter a sentence: ')
words = sentence.split()
print('Words:', len(words))
for w in words:
print(w, 'has', len(w), 'letters')Enter a sentence: learn python at lambdalab Words: 4 learn has 5 letters python has 6 letters at has 2 letters lambdalab has 9 letters
words = sentence.split()Split once, into a name. Writing sentence.split() again inside the loop would do the same work on every round, and it is the kind of thing that gets you a comment rather than a mark.
for w in words:The same loop shape as for ch in word — only the list is a list of words, so w holds a whole word. Nothing new is being learnt here except what is in the box.
3Program 2 — the longest word
Find the longest word in a sentence, and say how long it is.
# the longest word in a sentence
sentence = 'practice makes a programmer perfect'
words = sentence.split()
longest = words[0]
for w in words:
if len(w) > len(longest):
longest = w
print('The longest word is', longest)
print('It has', len(longest), 'letters')The longest word is programmer It has 10 letters
words[0], not as ''. An empty string would work here by luck — every real word is longer than nothing — but the honest starting value for “the best so far” is a real member of the list. It is the same rule as starting a highest-mark search at marks[0], and it is the one that keeps working when the comparison is not about length.Ties go to the first word, because the test is > and not >= — a later word of equal length never displaces the champion. Worth knowing, because “longest word” questions with two equal answers are common and both answers cannot be right.
4Program 3 — the words in the opposite order
Turn python makes strings easy into easy strings makes python — the words reversed, but each word still spelt forwards.
# the words in the opposite order
sentence = 'python makes strings easy'
words = sentence.split()
result = ''
for i in range(len(words) - 1, -1, -1):
result = result + words[i]
if i > 0:
result = result + ' '
print(result)easy strings makes python
The backwards walk from the index page, over a list instead of a string — range(len(words) - 1, -1, -1) counts 3, 2, 1, 0. The if i > 0 is the fence-post rule again: four words need three spaces between them, so the space is skipped on the last round, which here is the round where i is 0.
sentence[::-1] gives 'ysae sgnirts sekam nohtyp' — every character backwards, so the words are spelt backwards too. Two different questions, and papers ask both.5Program 4 — initials from a name
Turn a full name into its initials: a p j abdul kalam becomes A.P.J.A.K.
# the initials of a name
name = input('Enter a full name: ')
words = name.split()
initials = ''
for w in words:
initials = initials + w[0].upper() + '.'
print('Initials:', initials)Enter a full name: a p j abdul kalam Initials: A.P.J.A.K.
w[0] is the first character of the word — indexing a string that came out of a list, which is the ordinary thing it looks like. Two additions per round, the letter and the dot, so no fence-post problem: every initial gets a dot, including the last.
w[0] would fail on an empty word. split() never produces one, which is why this program is safe — but a program that split on a fixed character, like name.split(','), can get an empty piece from 'a,,b', and ''[0] raises IndexError: string index out of range.6Program 5 — the words that start with a given letter
Print every word of a sentence that begins with a chosen letter, and count them.
# the words that begin with a chosen letter
sentence = 'sam sold seven small silver shells on sunday'
letter = 's'
count = 0
for w in sentence.split():
if w[0] == letter:
count = count + 1
print(w)
print(count, 'words begin with', letter)sam sold seven small silver shells sunday 7 words begin with s
The loop runs over sentence.split() directly, without a name in between — fine when the list is used once. w[0] is the first letter and w[-1] would be the last, if the question asked for words ending in something.
7Program 6 — the average word length
Work out the average number of letters per word.
# the average length of the words in a sentence
sentence = 'a programmer writes readable programs'
words = sentence.split()
total = 0
for w in words:
total = total + len(w)
print('Words:', len(words))
print('Letters:', total)
print('Average word length:', total / len(words))Words: 5 Letters: 33 Average word length: 6.6
len(words), not by len(sentence). The two are 5 and 37 here, and the second would give an answer under 1 that still looks like a number. And the division goes after the loop: inside it, you would be dividing a part-finished total by the full count.8Recap
It hands back a list of words. A for loop over that list gives whole words, and each one is an ordinary string.
words = sentence.split() above the loop. Calling it again inside repeats the same work every round.
A real member of the list, not '' or 0. Ties go to the first word, because the test is > and not >=.
Reversing the list keeps each word spelt forwards; sentence[::-1] spells every word backwards too.
- 1
Print the shortest word in a sentence.
Hint · Program 2 with
<instead of>. The champion still starts atwords[0]. - 2
Count the words that have more than five letters.
Hint · A counter above the loop and
len(w) > 5inside it. - 3
Print each word with its first letter capitalised, on one line.
Hint · Build the line with
w[0].upper() + w[1:] + ' '— a slice from 1 is the rest of the word. - 4
Count how many words are palindromes.
Hint · The palindrome test from the searching page, applied to
winside this loop. - 5
Report the word that contains the most vowels.
Hint · A loop inside a loop: words on the outside, characters of
won the inside, and a champion for the best count so far.
What does sentence.split() hand back?
A longest-word program starts longest = ''. Two words tie for longest. Which is reported?
Which gives 'easy strings makes python' from 'python makes strings easy'?