In this chapter, we have learned how to define a dictionary, add or modify the key/value pairs, search through the keys and values, and loop through the collection. However, we still need to understand what dictionaries allow us to do.
First, neither collection is better than the other. They are just different. There are some problems that lists solve more easily, while dictionaries are the better choice for other tasks.
The question isn’t which collection is better than the other. The proper question is which data structure best fits the job at hand.
Let’s take a look at one task where using a dictionary really helps.
Google provides an easy-to-use algorithm that translates simple words and phrases between languages.
While we cannot build something as complete as this app (yet), we CAN understand how to make something similar with Python. At its core, the program is built around a dictionary!
Take a look at this small English-to-Spanish dictionary. The keys are English words, and the values are the same words in Spanish:
1 2 3 4 5 6 7 | eng_to_span = {
'hello' : 'hola',
'blue' : 'azul',
'apple' : 'manzana',
'python' : 'pitón',
'library' : 'biblioteca'
}
|
Now imagine that a user inputs an English word. We can easily search the keys
in the eng_to_span
dictionary for that word. If we find it, we can print
the value for that key, which is the Spanish translation.
That’s it! Our word translator is limited only by the size and accuracy of the dictionary.
Try It!
Add key/value pairs to the translate
dictionary! Feel free to use words
from any two languages you want, but you must be able to type in the starting
words with the letters on your keyboard.
Walking through the code:
keep_going = True
keeps the while
loop running until the user tells
the program to stop.word_to_change
input statement prompts the user for the word to
translate.if word_to_change in translate
checks to see if the entered word is one
of the keys in the dictionary.True
, then print(translate[word_to_change])
displays the value
for the key.False
, then the user sees a message telling them that their word
is missing from the dictionary.repeat
input statement asks the user if they would like to keep
going. Any entry that does NOT start with 'y'
(repeat[0].lower() != 'y'
) sets keep_going
to False
, and the
program ends.Note
We could build the translation app with lists, but that code would be less efficient and more likely to have bugs.
Explain why.
Once we complete a language-to-language dictionary, we can use it to translate more than just single words. Earlier in this chapter, we created a dictionary that linked words in pirate-speak with their English meanings. Let’s use this to have a little fun!
Our next task will take a set of text and replace some of the English words with pirate-speak. Follow the instructions listed below the editor to complete the program. You can also see the steps by clicking the Instructions tab in the editor.
Instructions:
Note that the English-to-pirate dictionary is defined in the
translate.py
module.
translate.py
and then import only the ones we want
into different programs.translate.py
get applied to all
programs that import it.eng_to_pirate
!Line 3 assigns the string we want to translate to the text
variable, and
line 4 splits text
into a list of separate words. Line 6 defines an
empty list to hold the words that go into the translated string.
On line 7, set up a for
loop to iterate through the list of words:
7 | for word in eng_words:
|
Now set up a conditional to check if word
is a key in the
eng_to_pirate
dictionary. If True
, append the value for the key
to the new_words
list. If False
, append the original word.
8 9 10 11 | if word in eng_to_pirate:
new_words.append(eng_to_pirate[word])
else:
new_words.append(word)
|
After the loop is done, join the elements from the new_words
list into
a new string, then print the result.
13 14 | new_text = ' '.join(new_words)
print(new_text)
|
Now run the program, fixing any syntax, runtime, or logic errors. Properly done, the output should look like:
If ye be interested in tales with happy endings, ye would be better off reading some other book.
Nice! Feel free to change the value of text
to try out different
translations.
Note
Right now, our translation program does NOT consider case or punctuation. We will fix this in the sections below.
Change you
to You
in the text and run the program again. Notice that
it leaves the capitalized word alone. All of the keys in eng_to_pirate
are
lowercase strings, so You
isn’t found.
Let’s add some logic to deal with capitalized words:
Change the if
statement to search for word
in lowercase. Note that
we also need to update the first append
statement:
8 9 | if word.lower() in eng_to_pirate:
new_words.append(eng_to_pirate[word.lower()])
|
Run the program again, and note that You
gets changed to ye
.
This is better, but not quite complete. The next fix is to replace
capitalized words with capitalized translations.
Change the if
statement one more time to also check if word
starts
with a capital letter. If True
we can retrieve the translated word and
then apply another string method to capitalize it.
8 9 10 | if word.lower() in eng_to_pirate and word[0].isupper():
new_word = eng_to_pirate[word.lower()]
new_words.append(new_word.capitalize())
|
Run the program again. Woo, hoo! You
translates to Ye
! But wait,
now nothing else in text
gets converted! The way the if
statement
works now, only capitalized English words get changed.
To fix this, add an elif
statement to bring back the original check and
translation statements:
11 12 | elif word in eng_to_pirate:
new_words.append(eng_to_pirate[word])
|
Our program now replaces both lowercase words and capitalized words.
When we split text
into a list of separate strings, punctuation marks
remain attached to the words. Since the keys in the eng_to_pirate
dictionary don’t include punctuation, strings like 'Stop!'
remain the
same.
We won’t step through building the code like we did above. Instead, here is one way to deal with periods, commas, and exclamation points. Feel free to paste this into your code above:
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | for word in eng_words:
punctuation = '' # Start 'punctuation' as the empty string.
# Check if 'word' ends with a period, comma or !
if word[-1] == '.' or word[-1] == ',' or word[-1] == '!':
punctuation = word[-1] # Save the punctuation mark.
word = word[:-1] # Reassign 'word' WITHOUT the mark.
if word[0].isupper() and word.lower() in eng_to_pirate:
new_word = eng_to_pirate[word.lower()] # Translate 'word'.
# Append 'new_word' combined with any saved punctuation mark.
new_words.append(new_word.capitalize() + punctuation)
elif word in eng_to_pirate:
# Append translated word plus any saved punctuation mark.
new_words.append(eng_to_pirate[word] + punctuation)
else:
# Append original word plus any saved punctuation mark.
new_words.append(word + punctuation)
|
Try entering different phrases for text
to check that the punctuation and
capitalization code works.
Examples
Text: "Stop! Go Meet The Principal in the cafeteria."
Translation: "Avast! Go Meet Th' Scallywag in th' swill dungeon."
Text: "Put away your phone and focus on the computer!"
Translation: "Put away yer cursed device and focus on th' magic
box!"
Text: "Listen to your teacher."
Translation: "Listen ta yer wise sage."