 Lists are great for things like the weekly or monthly temperatures where you naturally index by the position in the list. What if we had a program that asks for the name of a country and then tells you the population of that country? Here's such a program using something called parallel lists. Each entry in the country's list has the population in the corresponding location in the population list. Here's our main program. We ask for a country and if the country is in the country's list, we find its position using index and then print its population by going into the corresponding entry in the population list. And if the country isn't in the country's list, then we simply say that we can't find the country. Let's run this program to see how it works. If I say Denmark and Greece, those work and a country that's not in our list yet would be Croatia, and it can't find that country. There's nothing wrong with this program. But if we were to add a new country, say Croatia, in alphabetical order in our list here, we'd have to make sure that we put the population 4,154,200 in the exact corresponding location in the population list. This is an error-prone operation and it just feels awkward. Let's run the program again real quick. Denmark still has the correct population and now Croatia shows up in our list. What we want is some data structure that makes this sort of thing easier. And that data structure is the Python dictionary. Let's think about using a real dictionary. Dictionaries aren't indexed by word. When you want the word atom defined, you don't look to see that it's word number 3472 and then look for definition number 3472. You look up the word atom by name and right next to it is the definition. And this is exactly what a Python dictionary lets you do. Here's the start of a dictionary-based version of the countries and population program. On line 5, we have a dictionary defined. Instead of using square brackets, which are for lists, we use curly braces. Inside the curly braces, we give our keys the things we want to index on, a colon, and the values for that index. So for the key Belgium, the value is 11,358,357. And for the key Greece, the value is 11,183,716. Let's go to the shell and do some experimenting. Although you use braces to define a dictionary, you still use square brackets when you index into it. Country pop of Denmark. I use square brackets and country pop Greece. If I try to use as my index value a value that isn't in the dictionary, such as Croatia, I get a key error. I can avoid getting a key error by using the in or not in operators. I can ask is Denmark in country pop? True is Croatia in country pop? False. So by checking first to see if the key is in the dictionary, I can avoid having key errors. Let's see how we have to change our main function. I've copied and pasted it from the previous program. First, the name of the list countries has to now become country pop our dictionary. Because we're using a dictionary, we don't have to find an index number. The key is our index. And here instead of saying population at our index, we go directly and say look in the dictionary for the country in question and that will retrieve the population. That's it. I've run the program to see that it works. If I say Greece and Denmark and Croatia, we get the same results as before. So what is using a dictionary really bought us? The real thing that is bought us is the index and value are now in one data structure and not two. If I add Croatia now, I can go to the correct place, say Croatia as the key, colon, and then the value 4,154,200. This is just ever so much more convenient. Let's check to see that that works. Greece, Denmark, and now Croatia has been added to our list of countries. In addition to using square brackets to access a dictionary, you can also use the get method. I can say countrypop.get of Germany. And I can do countrypop.get of, let's say, Czechia, which we have not added yet. The latter call returns a special value none, which does not print out as anything. I can show you that. Let's do countrypop.get of Czechia is equal to none, and that's true. If you don't like having none as a value, you can give a second argument to get that gives an alternate value in case the key is not found. If I say countrypop.get Germany, zero. If Germany is found, it will return its value, otherwise zero. Since Germany is in our countrypopulation dictionary, we get the value. If I do countrypop.get with Ghana, not in the dictionary, and zero, I get my alternate value of zero. One other important thing that we need to do is iterate through a dictionary. Here's one way to do it. I can say for country in countrypop, print country and countrypop of country. This for loop will go through all the keys in the dictionary, and then print in the body of the loop, and there we have it. In this case, the countries happen to be in alphabetical order, but there's no guarantee of this. Keys are placed in the dictionary in a way that makes it easy for Python to access them, and if that happens to be the same as the order in which you entered them, well, that just happens to be good luck. Another way to iterate through a dictionary is with the items method, which gives you both the key and value, again in whichever order the dictionary stores it. I can say for country,pop, which returns both values in countrypop.items, print country and population. Finally, let's look at a program that creates a dictionary from scratch. We're going to create an empty dictionary on line six, set a finished flag to false, and as long as we're not finished, we're going to ask the user for a name. If the name is not the empty string, we'll then ask for an age, and this is how you enter something into a dictionary. You say people subname equals age, and you put the dictionary access on the left-hand side of the equal sign. If they did enter the empty string, we're finished, and then after we've entered all the names, we're going to use our items method again to get the names and ages, and print them all out. Let's run that program. I'll put Joe as 29. Let's have Federico be 18. Let's have Nancy be 29. What happens if I put Joe in again, and he's now 22 instead of 29? I mixed up his age with Nancy's. It's not an error. It just replaces the value for that key. And let's put in somebody named Albert, who's 17. All right, he's 29. And Qua, who's 35, 36. I have a lot of people who are 29 years old, it would seem. And then when I press Enter to quit, I get the names and ages. What if I want to make sure that I have the items in sorted order? Let's go to the shell to give you an example. I'll create a small dictionary here. Let's put Jim and make him 26. Let's put in Alan and make him 37. And put in Barbara and make her 48 for her age. If I say name keys equals example.keys, and look at that, it gives me back a special structure called dictionary keys that has only the keys from the dictionary. I can't use this in a for loop, though, unless I convert it to a list. So let's make name list to be the list form of example keys. And now if I look at name list, I've got Jim, Alan and Barbara. I can sort it in place by saying name list dot sort. And now if I look at it, I have them in alphabetical order. And I can say for name in name list, print is years old dot format, name example of name. And now I have them in alphabetical order. Let's modify our program to make use of this so that our people in the dictionary that we've created come out in alphabetical order. We'll put name list equals list of people dot keys. And then we'll sort the name list. And then instead of using the items method, we're going to have to go back to the other way that we iterated through it. We'll have to say for name in name list. Instead of the age, we have to go into people of name. Let's save that and run it and see if it works. We'll have Federico, who's 19, Barbara, who's 20, Jorge, who's 35, Thomas, who's 22, and Steve, who's 47. And there they are in alphabetical order.