Home
Map
Dictionary ExamplesAdd keys and values, and then look them up, with a dictionary. Test lookup performance.
Python
This page was last reviewed on Feb 1, 2024.
Dictionary. In a dictionary we map keys to values. Python dictionaries are maps. With square brackets, we assign and access a value at a key.
Shows a dictionaryShows a dictionary
Dictionary methods. With get() we can specify a default result. Python is "batteries included," so it provides many helpful methods upon dictionaries.
KeyError
List
Get. Here we use the get method and the direct access approach to accessing keys in a dictionary. Using get() in Python is important—it is one of the first things to learn.
Part 1 This is the setup code. We populate a dictionary with 2 keys and 2 values for those keys.
Part 2 We then directly access a value. This direct access does not handle error conditions well.
Part 3 Get() receives the key you are testing, and (optionally) a value returned if the key is not found.
Shows a dictionary
# Part 1: add 2 key-value tuples to the dictionary. plants = {} plants["radish"] = 2 plants["squash"] = 4 # Part 2: direct access. print("radish:", plants["radish"]) # Part 3: get method calls. if (result := plants.get("squash")) != None: print("squash:", result) print("tuna:", plants.get("tuna")) print("tuna:", plants.get("tuna", "no tuna found"))
radish: 2 squash: 4 tuna: None tuna: no tuna found
Keys. A non-empty dictionary has keys. Here we create a dictionary of 3 key-value pairs. This dictionary could be used to store hit counts on a website's pages.
Here We introduce 2 variables, named keys and values. These are not lists—but we can convert them to lists.
Convert
Shows a dictionary
hits = {"home": 125, "sitemap": 27, "about": 43} keys = hits.keys() values = hits.values() print("Keys:") print(keys) print(len(keys)) print("Values:") print(values) print(len(values))
Keys: dict_keys(['home', 'about', 'sitemap']) 3 Values: dict_values([125, 43, 27]) 3
Initialize. To begin we show 3 different ways of creating a dictionary with 3 keys and 3 values (3 items). The keys are color names, and values are integers.
Part 1 We create a dictionary with an expression. This syntax requires that we know exactly what is to be placed in the dictionary.
Part 2 We create an empty dictionary, and then assign elements into it. This can be done with a dictionary that already has elements.
Part 3 We have an iterable that contains 2-element tuples. We can pass this to the dict built-in to get a dictionary.
dict
# Part 1: use literal expression. colors1 = {"cyan": 5, "peach": 7, "pink": 9}; print(colors1) # Part 2: create empty dictionary, then assign. colors2 = {} colors2["cyan"] = 5 colors2["peach"] = 7 colors2["pink"] = 9 print(colors2) # Part 3: create list of 2-element tuples. # ... Then use dict. items = [("cyan", 5), ("peach", 7), ("pink", 9)] colors3 = dict(items) print(colors3)
{'cyan': 5, 'peach': 7, 'pink': 9} {'cyan': 5, 'peach': 7, 'pink': 9} {'cyan': 5, 'peach': 7, 'pink': 9}
Get, none. In Python "None" is a special value like null or nil. We often use None in programs. It means no value. Get() returns None if no value is found in a dictionary.
Info We see a None value for "carrot." So get() can return None, but there is actually a None value in the dictionary.
lookup = {"bird": 10, "carrot": None} # A value can be none. print("GET:", lookup.get("carrot")) print("GET:", lookup.get("xyz"))
GET: None GET: None
Get, frequencies. A dictionary (and its get method) can be used to count letter frequencies. We use get() on a dictionary to start at 0 for nonexistent values.
So The first time a letter is found, its frequency is set to 0 + 1, then 1 + 1. Get() has a default return.
# The first three letters are repeated. letters = "abcabcdefghi" frequencies = {} for c in letters: # If no key exists, get returns the value 0. # ... We then add one to increase the frequency. # ... So we start at 1 and progress to 2 and then 3. frequencies[c] = frequencies.get(c, 0) + 1 for f in frequencies.items(): # Print the tuple pair. print(f)
('a', 2) ('c', 2) ('b', 2) ('e', 1) ('d', 1) ('g', 1) ('f', 1) ('i', 1) ('h', 1)
Dict.fromkeys. Suppose we have a list (or other iterable) of keys, but no values in particular. We can use dict.fromkeys, and specify a default value.
Here We invoke dict.fromkeys and then call get() to search for a couple keys inside the dictionary.
animals = ["bird", "frog"] # Initialize a dictionary from a list of keys. # ... Set all values to 100. result = dict.fromkeys(animals, 100) print("RESULT:", result) print("FROG: ", result.get("frog")) print("?: ", result.get("?"))
RESULT: {'bird': 100, 'frog': 100} FROG: 100 ?: None
Update. We can use update to initialize a dictionary. We start with an empty dictionary, and then pass other dictionaries to the update() method.
And Our dictionary is populated with the desired keys and values. And only one method is needed.
# Start with an empty dictionary. # ... Initialize it with update() calls. ids = {} print("START: ", ids) # Call update twice. ids.update({"abc123": 30, "def123": 20}); print("UPDATE 1:", ids) ids.update({"xyz987": 40}) print("UPDATE 2:", ids)
START: {} UPDATE 1: {'abc123': 30, 'def123': 20} UPDATE 2: {'abc123': 30, 'def123': 20, 'xyz987': 40}
Empty dictionary. For further illustration, let us consider what happens when we update an empty dictionary. The dictionary gets all the keys and values from the update.
test = {} # Update an empty dictionary. test.update({"bird": 10, "frog": 20}) print(test)
{'bird': 10, 'frog': 20}
Sorted keys. In a dictionary, keys are not sorted in any way—they are unordered. Their order reflects the internals of the hashing algorithm's buckets.
sort
But Sometimes we need to sort keys. We invoke another method, sorted(), on the keys. This creates a sorted view.
# Same as previous program. hits = {"home": 124, "sitemap": 26, "about": 32} # Sort the keys from the dictionary. keys = sorted(hits.keys()) print(keys)
['about', 'home', 'sitemap']
Items. Here we create a dictionary and call items(). With tuples, we can address the first element with an index of 0. The second element has an index of 1.
Info The code uses a for-loop on the items() iterable. It uses the print() method with 2 arguments.
rents = {"apartment": 1000, "house": 1300} # Convert to iterable of tuples. rentItems = rents.items() # Loop and display tuple items. for rentItem in rentItems: print("Place:", rentItem[0]) print("Cost:", rentItem[1]) print("")
Place: house Cost: 1300 Place: apartment Cost: 1000
Items, unpack. The items() iterable can be used in another for-loop syntax. We can unpack the 2 parts of each tuple in items() directly in the for-loop.
Here In this example, we use the identifier "k" for the key, and "v" for the value.
# Create a dictionary. data = {"a": 1, "b": 2, "c": 3} # Loop over items and unpack each item. for k, v in data.items(): # Display key and value. print(k, v)
a 1 c 3 b 2
Invert keys, values. Sometimes we want to invert a dictionary—change the values to keys, and the keys to values. Complex solutions are possible. But we can do this with items() and a loop.
reptiles = {"frog": 20, "snake": 8} inverted = {} # Use items loop. # ... Turn each value into a key. for key, value in reptiles.items(): inverted[value] = key print(":::ORIGINAL:::") print(reptiles) print(":::KEYS, VALUES SWAPPED:::") print(inverted)
:::ORIGINAL::: {'frog': 20, 'snake': 8} :::KEYS, VALUES SWAPPED::: {8: 'snake', 20: 'frog'}
For-loop example. Here we see the simplest for-loop over a dictionary. But by directly looping over the dictionary, we may need to access the values for each later.
And This could lead to more complexity because we must call get() in some programs. Using items() in the for-loop would avoid this.
Here The plant variable, in the for-loop, is the key. The value is not available—we would need get() to access it.
plants = {"radish": 2, "squash": 4, "carrot": 7} # Loop over dictionary directly. # ... This only accesses keys. for plant in plants: print(plant)
radish carrot squash
For, items. We can call the items() method to get a list of tuples. No extra hash lookups will be needed to access values. We can unpack each tuple directly in the loop statement.
Tip In my experience this is the best way to loop over a Python dictionary in most real programs.
So Make sure to remember the "items" and unpacked tuple pattern for dictionary loops.
color_codes = {"blue": 10, "red": 20} # Loop over items(). # ... Unpack into a 2-item tuple. for (color_name, color_code) in color_codes.items(): print("NAME:", color_name) print("CODE:", color_code)
NAME: blue CODE: 10 NAME: red CODE: 20
Copy. We first create a dictionary with 3 keys and 3 values. We create a copy of the original dictionary. We then modify values within the copy.
Important After copying the dictionary, the original is not affected when we modify the copy. The 2 dictionaries are separate.
original = {"box": 1, "cat": 2, "apple": 5} # Create copy of dictionary. modified = original.copy() # Change copy only. modified["cat"] = 200 modified["apple"] = 9 # Original is still the same. print(original) print(modified)
{'box': 1, 'apple': 5, 'cat': 2} {'box': 1, 'apple': 9, 'cat': 200}
Copy, dict. There are other ways to copy a dictionary in Python. The dict built-in method can be used in the same way as copy(). This program shows the syntax.
Part 1 We invoke the copy() method on a dictionary to copy the entire contents of the original dictionary.
Part 2 We use the dict built-in method to copy the dictionary. This has the same effect as the copy() method.
Part 3 We print the contents of the original dictionary that was copied twice, and it is unchanged.
original = {"red": 0, "blue": 10} # Part 1: use copy() to duplicate a dictionary. copy1 = original.copy() copy1["red"] = 1000 print(copy1) # Part 2: use dict keyword to copy. copy2 = dict(original) copy2["red"] = 2000 print(copy2) # Part 3: original is unchanged. print(original)
{'red': 1000, 'blue': 10} {'red': 2000, 'blue': 10} {'red': 0, 'blue': 10}
Fromkeys. Here we invoke dict.fromkeys on a string list. If you specify the second argument to fromdict(), each key has that value in the newly-created dictionary.
Tip We create the dictionary without a for-loop. Logically, dict.fromkeys contains its own loop.
# A list of keys. keys = ["bird", "plant", "fish"] # Create dictionary from keys. d = dict.fromkeys(keys, 5) # Display. print(d)
{'plant': 5, 'bird': 5, 'fish': 5}
No default value. We can invoke dict.fromkeys with no second argument. This means that each key has the special value of None—the keys are still in the dictionary, but have values of None.
Info In this program, the in-keyword still finds the keys in the dictionary with values of None.
in
values = [10, 20, 30] # Use fromkeys to create keys with values of None. lookup = dict.fromkeys(values) if 10 in values: print("HAS 10") if 300 in values: # Not reached. print("HAS 300")
HAS 10
Benchmark, get. I compared a loop that uses get() with one that uses both the in-keyword and a second look up. Version 2, with the "in" operator, was faster.
Version 1 This version uses a second argument to get(). It tests that against the result and then proceeds if the value was found.
Version 2 This version uses "in" and then a lookup. Twice as many lookups occur. But fewer statements are executed.
Result It is faster to use the in-operator to test the contents of a dictionary. This approach should be preferred when possible.
import time # Input dictionary. systems = {"mac": 1, "windows": 5, "linux": 1} print(time.time()) # Version 1: use get. v = 0 x = 0 for i in range(10000000): x = systems.get("windows", -1) if x != -1: v = x print(time.time()) # Version 2: use in. v = 0 for i in range(10000000): if "windows" in systems: v = systems["windows"] print(time.time())
1478552825.0586164 1478552827.0295532 (get = 1.97 s) 1478552828.1397061 (in = 1.11 s)
Benchmark, for. A dictionary can be looped over in different ways. In this benchmark we test 2 approaches. We access the key and value in each iteration.
Version 1 This version loops over the keys of the dictionary with a while-loop. It then does an extra lookup to get the value.
Version 2 This version instead uses a list of tuples containing the keys and values. It does not touch the original dictionary.
Result Looping over a list of tuples is faster than looping over a dictionary. This makes sense—with the list, no lookups are done.
import time data = {"parrot": 1, "frog": 1, "elephant": 2, "snake": 5} items = data.items() print(time.time()) # Version 1: get. for i in range(10000000): v = 0 for key in data: v = data[key] print(time.time()) # Version 2: items. for i in range(10000000): v = 0 for tuple in items: v = tuple[1] print(time.time())
1478467043.8872652 1478467048.6821966 (version 1 = 4.79 s) 1478467053.2630682 (version 2 = 4.58 s)
With dictionaries, a special hashing algorithm translates a key (often a string) into an integer. For a speedup, this integer is used to locate the data.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Feb 1, 2024 (edit).
Home
Changes
© 2007-2024 Sam Allen.