Home
Search
Python Dictionary ExamplesAdd keys and values, and then look them up, with a dictionary. Test lookup performance.
dot net perls
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.
Dictionary methods. With get() we can specify a default result. Python is "batteries included," so it provides many helpful methods upon dictionaries.
KeyError
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 The first argument to get() is the key you are testing. The second argument is a value returned if the key is not found.
Python program that gets values
# Part 1: add 2 key-value tuples to the dictionary. plants = {} plants["radish"] = 2 plants["squash"] = 4 # Part 2: direct access. print(plants["radish"]) # Part 3: get method calls. print(plants.get("squash")) print(plants.get("tuna")) print(plants.get("tuna", "no tuna found"))
2 4 None 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.
Views We introduce 2 variables, named keys and values. These are not lists—but we can convert them to lists.
Convert
Python program that uses keys
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 A We create a dictionary with an expression. This syntax requires that we know exactly what is to be placed in the dictionary.
Part B We create an empty dictionary, and then assign elements into it. This can be done with a dictionary that already has elements.
Part C We have an iterable that contains 2-element tuples. We can pass this to the dict built-in to get a dictionary.
dict
Python program that initializes dictionary
# Part A: use literal expression. colors1 = {"cyan": 5, "peach": 7, "pink": 9}; print(colors1) # Part B: create empty dictionary, then assign. colors2 = {} colors2["cyan"] = 5 colors2["peach"] = 7 colors2["pink"] = 9 print(colors2) # Part C: 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.
Program We see a None value for "carrot." So get() can return None, but there is actually a None value in the dictionary.
Python program that shows None in 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.
Python program that counts letter frequencies
# 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.
Python program that creates dictionary with fromkeys
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.
Python program that initializes with update
# 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.
Python program that uses update on empty dictionary
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.
Python program that sorts keys in dictionary
# 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.
Tuple
Info The code uses a for-loop on the items() iterable. It uses the print() method with 2 arguments.
Console, print
Python program that uses items method
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.
Python program that unpacks items
# 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.
Python program that inverts a dictionary
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.
Python program that loops over dictionary
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.
Python program that loops over items
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.
Python program that uses copy
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 A We invoke the copy() method on a dictionary to copy the entire contents of the original dictionary.
Part B We use the dict built-in method to copy the dictionary. This has the same effect as the copy() method.
Part C We print the contents of the original dictionary that was copied twice, and it is unchanged.
Python program that uses copy and dict built-in method
original = {"red": 0, "blue": 10} # Part A: use copy() to duplicate a dictionary. copy1 = original.copy() copy1["red"] = 1000 print(copy1) # Part B: use dict keyword to copy. copy2 = dict(original) copy2["red"] = 2000 print(copy2) # Part C: 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.
Python program that uses fromkeys
# 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
Python program that uses fromkeys, no default value
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.
Python program that benchmarks get
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.
Python program that benchmarks loops
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)
Memoize. One classic optimization is called memoization. And this can be implemented easily with a dictionary. In memoization, a function (def) computes its result.
Memoize
And Once the computation is done, it stores its result in a cache. In the cache, the argument is the key. And the result is the value.
KeyError. If we try to access a key that is not present with direct syntax, we will get a KeyError. This can be avoided with the get() method.
Counter. For frequencies, we can use a special Counter from the collections module. This can make counters easier to add in programs.
Counter
A summary. 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.
Home
© 2007-2021 sam allen. send bug reports to info@dotnetperls.com.