Here some bits of info about python dictionaries & looping through them.
Extra special beginner stuff.
What is a dictionary?
A python dictionary is an extremely useful data storage construct for storing and retreiving key:value pairs.
Many languages implement simple arrays (lists in python) that are keyed by a integer. For example, if you made a list [1, 2] – the first value would be retrieved via [1, 2][0].
my_list = [1, 2, 3]
my_list[0]
# Out: 1
my_list[1]
# Out: 2
A dictionary is a little more advanced in that the keys can be many other things than integers. Often times the key will be a string merely for the fact that it’s easy for a human to recall.
Will I remember that my_list[3] is my phone number? Not nearly as well as if I have a key named “phone_number”.
my_dict = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3'
}
my_dict['key1']
# Out: 'value1'
Major differences vs lists
– Keys are any hashable object (say strings for simplicity)
– Are NOT ordered (a list is by definition ordered)
One way I like to think about them are as little variable containers. The fact that they are wrapped in a container makes them quite useful and versatile since you can easily move the “container” around.
In fact, variables are very much related to dictionaries! Whenever you declare a variable (x=3), that variable is accessible by its string name (‘x’) via the dictionary returned by the builtin function ‘locals()’ or ‘vars()’.
Watch and see:
var1 = 'val1' # local variable definition
var2 = 'val2'
locals_dict = locals()
print locals_dict['var1']
# Out: val1
container = {}
container['var1'] = 'val1'
print container['var1']
# Out: val1
Looping through dictionaries
Now, if you did a little experimenting, you would see that if you loop through a dictionary you loop through its keys.
>>> my_dict = {
... 'key1': 'value1',
... 'key2': 'value2',
... 'key3': 'value3'
... }
>>> for item in my_dict:
... print item
...
key3
key2
key1
Note that this is the equivalent of looping through “my_dict.keys()”
What about getting the values?
Based on what we’ve learned, you could always use the keys you are iterating through to pull the value from the dictionary.
for item in my_dict:
print my_dict[item]
But there are better ways to get the values. Enter the “items” function.
We can ask the dictionary to return key, value pairs via the “items()” function.
for key, value in my_dict.items(): # returns the dictionary as a list of value pairs -- a tuple.
print key, value
More efficient dictionary loops
Calling “my_dict.items()” requires generating the entire list of key-value pairs in-memory. Sometimes, if your dictionary is too large, this can be a severe performance bottleneck. To get around this problem we can create a generator via the “iteritems()” method.
A generator allows you to iterate one item at a time. Only the key and value are pulled into memory for every iteration and immediately discarded. There are methods for returning a key generator and value generator as well.
for key, value in my_dict.iteritems():
print key, value
for key in my_dict.iterkeys():
print key
for value in my_dict.itervalues():
print value
Note that one thing you can’t do with a generator is to delete a key during the generator loop.
for x, y in mydictionary:
del mydictionary[x]
# Out: RuntimeError: dictionary changed size during iteration
Sorting a Python Dictionary
Actually, python dictionaries can’t be sorted. We will have to turn them into lists to sort them.
# to my dictionary...
sorted_list = [x for x in my_dictionary.iteritems()]
sorted_list.sort(key=lambda x: x[0]) # sort by key
sorted_list.sort(key=lambda x: x[1]) # sort by value
# to reverse the sort
sorted_list.reverse()
Useful dictionary tips
Accessing a dictionary key that might not exist
Sometimes we know that a dictionary key might not exist. This happens a lot in loops where we don’t want to use a try/except block just to capture the exception.
For these situations we have the “get” method. Pass in the key as the first argument, and it will either return the value or None.
Pass in a second argument, and if the key doesn’t exist, it will return the second argument.
dict_ = {'key1':'value1'}
dict_.get('key1')
# out: 'value1'
dict_.get('key2')
# out: None
dict_.get('key2', "Key doesn't exist")
# out: Key doesn't exist
Get or insert into a dictionary if key doesn’t exist
Sometimes we need to insert a value if the key doesn’t exist in a dictionary. The previous “get” method only returns a value – the dictionary is unchanged.
dict_ = {}
dict_.setdefault('key1', 'value1')
# Out: value1
print dict_
# Out: { 'key1': 'value1' }
This can be extremely useful if you need to append to a list if it exists or otherwise create a blank list.
key_value_pairs = [
('key1', 'value'),
('key1', 'value2'),
('key1', 'value3'),
]
dict_ = {}
for key, value in key_value_pairs:
dict_.setdefault(key, []).append(value)
print dict_
# Out: { 'key1': ['value','value2','value3'] }
Generate a dictionary from tuples
It’s often useful to generate a dictionary from a list of tuples. For example, you could use a list comprehension to create a dictionary!
key_value_pairs = [
('key1', 'value'),
('key2', 'value2'),
('key3', 'value3'),
]
# now let's generate the same list of tuples via list comprehension
key_value_pairs = [('key{0}'.format(x), 'value{0}'.format(x)) for x in range(1, 4)]
dict_ = dict(key_value_pairs)
print dict_
# Out: {'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}
Conclusion
I’m a little surprised that this is one of my most visited blog posts.
It’s not written well, and it was written years ago!
Let me know if I can improve it… 😉