LOOPING THROUGH A DICTIONARY

Credit: The information below has been obtained from http://introtopython.org and used with permission under the MIT license. 

Up to this point, we have been printing out the key-value pairs of a dictionary one at a time. This can be very time consuming and takes up too many lines of code. It also does not help us should we need to check each element individually. Since dictionaries are really about connecting bits of information, you will often use them in the ways described above, where you add key-value pairs whenever you receive some new information, and then you retrieve the key-value pairs that you care about. Sometimes, however, you will want to loop through the entire dictionary. There are several ways to do this:

  • You can loop through all key-value pairs;
  • You can loop through the keys, and pull out the values for any keys that you care about;
  • You can loop through the values.

See below to learn how looping through a dictionary works.

LOOPING THROUGH ALL KEY-VALUE PAIRS

Dictionaries have their own for-loop syntax, but since there are two kinds of information in dictionaries, the structure is a bit more complicated than it is for lists. The main difference is that we need to make reference to both the key and the value in the loop. Here is how to use a for loop with a dictionary:

[python]
python_words = {‘list’: ‘A collection of values that are not connected, but have an order.’,
‘dictionary’: ‘A collection of key-value pairs.’,
‘function’: ‘A named set of instructions that defines a set of actions in Python.’,
}

# Print out the items in the dictionary.
for word, meaning in python_words.items():
print("Word:",word)
print("Meaning:",meaning)
[/python]

That certainly makes our job of accessing and printing each key-value much easier. The only tricky part about using for loops with dictionaries is figuring out what to call those first two variables. The general syntax for this loop is:

[python]
for key_name, value_name in dictionary_name.items():
print(key_name) # The key is stored in whatever you called the first variable.
print(value_name) # The value associated with that key is stored in your second variable.
[/python]

Since the method

[python light=”true”].items()[/python]

pulls all key-value pairs from a dictionary into a list of tuples (an immutable list).

[python]
my_dict = {‘key_1’: ‘value_1’,
‘key_2’: ‘value_2’,
‘key_3’: ‘value_3’,
}

print(my_dict.items())
[/python]

The syntax for

[python light=”true”]key, value in my_dict.items():[/python]

does the work of looping through this list of tuples, and pulling the first and second item from each tuple for us.

There is nothing special about any of these variable names, so Python code that uses this syntax becomes really readable. Rather than create a new example of this loop, let’s just look at the original example again to see this in a meaningful context:

[python]
python_words = {‘list’: ‘A collection of values that are not connected, but have an order.’,
‘dictionary’: ‘A collection of key-value pairs.’,
‘function’: ‘A named set of instructions that defines a set of actions in Python.’,
}

for word, meaning in python_words.items():
print("\nWord",word)
print("Meaning:",meaning)
[/python]

Try executing the code in the widget below. Change the code around in order to demonstrate your understanding.

LOOPING THROUGH ALL KEYS IN A DICTIONARY

Python provides a clear syntax for looping through just the keys in a dictionary:

[python]
my_dict = {‘key_1’: ‘value_1’,
‘key_2’: ‘value_2’,
‘key_3’: ‘value_3’,
}

# We’ll use a different syntax for printing strings in this section
# Ask your teacher if you don’t understand
for key in my_dict.keys():
print(‘Key: %s’ % key)
[/python]

This is actually the default behavior of looping through the dictionary itself. So you can leave out the

[python light=”true”].keys()[/python]

part, and get the exact same behavior:

[python highlight=”6″]
my_dict = {‘key_1’: ‘value_1’,
‘key_2’: ‘value_2’,
‘key_3’: ‘value_3’,
}

for key in my_dict:
print(‘Key: %s’ % key)
[/python]

The only advantage of using the .keys() in the code is a little bit of clarity. But anyone who knows Python reasonably well is going to recognize what the second version does. In the rest of our code, we will leave out the .keys() when we want this behavior.

You can pull out the value of any key that you are interested in within your loop, using the standard notation for accessing a dictionary value from a key:

[python highlight=”8,9″]
my_dict = {‘key_1’: ‘value_1’,
‘key_2’: ‘value_2’,
‘key_3’: ‘value_3’,
}

for key in my_dict:
print(‘Key: %s’ % key)
if key == ‘key_2’:
print(" The value for key_2 is %s." % my_dict[key])
[/python]

Let’s show how we might use this in our Python words program. This kind of loop provides a straightforward way to show only the words in the dictionary:

[python]
python_words = {‘list’: ‘A collection of values that are not connected, but have an order.’,
‘dictionary’: ‘A collection of key-value pairs.’,
‘function’: ‘A named set of instructions that defines a set of actions in Python.’,
}

# Show the words that are currently in the dictionary.
print("The following Python words have been defined:")
for word in python_words:
print("- %s" % word)
[/python]

We can extend this slightly to make a program that lets you look up words. We first let the user choose a word. When the user has chosen a word, we get the meaning for that word, and display it:

[python highlight=”11-13″]
python_words = {‘list’: ‘A collection of values that are not connected, but have an order.’,
‘dictionary’: ‘A collection of key-value pairs.’,
‘function’: ‘A named set of instructions that defines a set of actions in Python.’,
}

# Show the words that are currently in the dictionary.
print("The following Python words have been defined:")
for word in python_words:
print("- %s" % word)

# Allow the user to choose a word, and then display the meaning for that word.
requested_word = input("\nWhat word would you like to learn about? ")
print("\n%s: %s" % (requested_word, python_words[requested_word]))
[/python]

This allows the user to select one word that has been defined. If we enclose the input part of the program in a while loop, the user can see as many definitions as they’d like:

[python highlight=”11-19″]
python_words = {‘list’: ‘A collection of values that are not connected, but have an order.’,
‘dictionary’: ‘A collection of key-value pairs.’,
‘function’: ‘A named set of instructions that defines a set of actions in Python.’,
}

# Show the words that are currently in the dictionary.
print("The following Python words have been defined:")
for word in python_words:
print("- %s" % word)

requested_word = ”
while requested_word != ‘quit’:
# Allow the user to choose a word, and then display the meaning for that word.
requested_word = input("\nWhat word would you like to learn about? (or ‘quit’) ")
if requested_word in python_words.keys():
print("\n %s: %s" % (requested_word, python_words[requested_word]))
else:
# Handle misspellings, and words not yet stored.
print("\n Sorry, I don’t know that word.")
[/python]

This allows the user to ask for as many meanings as they want, but it takes the word “quit” as a requested word. Let’s add an elif clause to clean up this behavior:

[python highlight=”15-23″]
python_words = {‘list’: ‘A collection of values that are not connected, but have an order.’,
‘dictionary’: ‘A collection of key-value pairs.’,
‘function’: ‘A named set of instructions that defines a set of actions in Python.’,
}

# Show the words that are currently in the dictionary.
print("The following Python words have been defined:")
for word in python_words:
print("- %s" % word)

requested_word = ”
while requested_word != ‘quit’:
# Allow the user to choose a word, and then display the meaning for that word.
requested_word = input("\nWhat word would you like to learn about? (or ‘quit’) ")
if requested_word in python_words.keys():
# This is a word we know, so show the meaning.
print("\n %s: %s" % (requested_word, python_words[requested_word]))
elif requested_word != ‘quit’:
# This is not in python_words, and it’s not ‘quit’.
print("\n Sorry, I don’t know that word.")
else:
# The word is quit.
print ("\n Bye!")
[/python]

Feel free to run and/or alter any of the above listed code in the widget below.

LOOPING THROUGH ALL VALUES IN A DICTIONARY

Python provides a straightforward syntax for looping through all the values in a dictionary, as well:

[python]
my_dict = {‘key_1’: ‘value_1’,
‘key_2’: ‘value_2’,
‘key_3’: ‘value_3’,
}

for value in my_dict.values():
print(‘Value: %s’ % value)
[/python]

We can use this loop syntax to have a little fun with the dictionary example, by making a little quiz program. The program will display a meaning, and ask the user to guess the word that matches that meaning. Let’s start out by showing all the meanings in the dictionary:

[python]
python_words = {‘list’: ‘A collection of values that are not connected, but have an order.’,
‘dictionary’: ‘A collection of key-value pairs.’,
‘function’: ‘A named set of instructions that defines a set of actions in Python.’,
}

for meaning in python_words.values():
print("Meaning: %s" % meaning)
[/python]

Now we can add a prompt after each meaning, asking the user to guess the word:

[python highlight=”11-17″]
python_words = {‘list’: ‘A collection of values that are not connected, but have an order.’,
‘dictionary’: ‘A collection of key-value pairs.’,
‘function’: ‘A named set of instructions that defines a set of actions in Python.’,
}

# Print each meaning, one at a time, and ask the user
# what word they think it is.
for meaning in python_words.values():
print("\nMeaning: %s" % meaning)

guessed_word = input("What word do you think this is? ")

# The guess is correct if the guessed word’s meaning matches the current meaning.
if python_words[guessed_word] == meaning:
print("You got it!")
else:
print("Sorry, that’s just not the right word.")
[/python]

This is starting to work, but we can see from the output that the user does not get the chance to take a second guess if they guess wrong for any meaning. We can use a while loop around the guessing code, to let the user guess until they get it right:

[python highlight=”11-21″]
python_words = {‘list’: ‘A collection of values that are not connected, but have an order.’,
‘dictionary’: ‘A collection of key-value pairs.’,
‘function’: ‘A named set of instructions that defines a set of actions in Python.’,
}

# Print each meaning, one at a time, and ask the user
# what word they think it is.
for meaning in python_words.values():
print("\nMeaning: %s" % meaning)

# Assume the guess is not correct; keep guessing until correct.
correct = False
while not correct:
guessed_word = input("\nWhat word do you think this is? ")

# The guess is correct if the guessed word’s meaning matches the current meaning.
if python_words[guessed_word] == meaning:
print("You got it!")
correct = True
else:
print("Sorry, that’s just not the right word.")
[/python]

This is better. Now, if the guess is incorrect, the user is caught in a loop that they can only exit by guessing correctly. The final revision to this code is to show the user a list of words to choose from when they are asked to guess:

[python highlight=”6-11,22-24″]
python_words = {‘list’: ‘A collection of values that are not connected, but have an order.’,
‘dictionary’: ‘A collection of key-value pairs.’,
‘function’: ‘A named set of instructions that defines a set of actions in Python.’,
}

def show_words(python_words):
# A simple function to show the words in the dictionary.
display_message = ""
for word in python_words.keys():
display_message += word + ‘ ‘
print (display_message)

# Print each meaning, one at a time, and ask the user
# what word they think it is.
for meaning in python_words.values():
print("\n%s" % meaning)

# Assume the guess is not correct; keep guessing until correct.
correct = False
while not correct:

print("\nWhat word do you think this is?")
show_words(python_words)
guessed_word = input("- ")

# The guess is correct if the guessed word’s meaning matches the current meaning.
if python_words[guessed_word] == meaning:
print("You got it!")
correct = True
else:
print("Sorry, that’s just not the right word.")
[/python]

Feel free to run and/or alter any of the above listed code in the widget below.

LOOPING THROUGH A DICTIONARY IN ORDER

Dictionaries are quite useful because they allow bits of information to be connected. One of the problems with dictionaries, however, is that they are not stored in any particular order. When you retrieve all of the keys or values in your dictionary, you can’t be sure what order you will get them back. There is a quick and easy way to do this, however, when you want them in a particular order.

Let’s take a look at the order that results from a simple call to dictionary.keys():

[python]
python_words = {‘list’: ‘A collection of values that are not connected, but have an order.’,
‘dictionary’: ‘A collection of key-value pairs.’,
‘function’: ‘A named set of instructions that defines a set of actions in Python.’,
}

for word in python_words.keys():
print(word)
[/python]

The resulting list is not in order. The list of keys can be put in order by passing the list into the sorted() function, in the line that initiates the for loop:

[python highlight=”6″]
python_words = {‘list’: ‘A collection of values that are not connected, but have an order.’,
‘dictionary’: ‘A collection of key-value pairs.’,
‘function’: ‘A named set of instructions that defines a set of actions in Python.’,
}

for word in sorted(python_words.keys()):
print(word)
[/python]

This approach can be used to work with the keys and values in order. For example, the words and meanings can be printed in alphabetical order by word:

[python highlight=”7″]
python_words = {‘list’: ‘A collection of values that are not connected, but have an order.’,
‘dictionary’: ‘A collection of key-value pairs.’,
‘function’: ‘A named set of instructions that defines a set of actions in Python.’,
}

for word in sorted(python_words.keys()):
print("%s: %s" % (word.title(), python_words[word]))
[/python]

In this example, the keys have been put into alphabetical order in the for loop only; Python has not changed the way the dictionary is stored at all. So the next time the dictionary is accessed, the keys could be returned in any order. There is no way to permanently specify an order for the items in an ordinary dictionary, but if you want to do this you can use the OrderedDict structure.

Feel free to run and/or alter any of the above listed code in the widget below.

EXERCISES

Mountain Heights

  • Wikipedia has a list of the tallest mountains in the world, with each mountain’s elevation. Pick five mountains from this list.
    • Create a dictionary with the mountain names as keys, and the elevations as values.
    • Print out just the mountains’ names, by looping through the keys of your dictionary.
    • Print out just the mountains’ elevations, by looping through the values of your dictionary.
    • Print out a series of statements telling how tall each mountain is: “Everest is 8848 meters tall.”
  • Revise your output, if necessary.
    • Make sure there is an introductory sentence describing the output for each loop you write.
    • Make sure there is a blank line between each group of statements.

Mountain Heights 2

  • Revise your final output from Mountain Heights, so that the information is listed in alphabetical order by each mountain’s name.
    • That is, print out a series of statements telling how tall each mountain is: “Everest is 8848 meters tall.”
    • Make sure your output is in alphabetical order.