I recently published a couple articles on data type conversions. If you would like to read them, here they are:
– String to Number Conversions
– Converting String Representations of Binary, Octal and Hexadecimal Integers
– Number to String Conversions
Today we’ll learn how to convert lists to dictionaries. We’ll learn how to use the functions zip and dict.
Here’s the video version of this article:
Just as we can convert a dictionary to a list, we can convert a list to a dictionary as well. Suppose we have two lists: one with English words and the other with their German counterparts. We can make a dictionary out of them in a couple of steps:
>>> english_words = ["car", "hat", "house"]
>>> german_words = ["Auto", "Hut", "Haus"]
First we need the method zip(list1, list2):
>>> english_german_iterator = zip(english_words, german_words)
The method returns a list iterator:
>>> english_german_iterator
<zip object at 0x0000023A5504D448>
If you want to read more about iterators, feel free to read this article.
Then we have to use the list method to convert the list iterator into a list:
>>> english_german_translations = list(english_german_iterator)
>>> english_german_translations
[('car', 'Auto'), ('hat', 'Hut'), ('house', 'Haus')]
What we get is a list of 2-tuples, where the first element in each tuple corresponds to a key in the dictionary we’re gonna convert the lists into and the second element will be the value. We can convert this list into a dictionary using the method dict(list):
>>> translations_dictionary = dict(english_german_translations)
>>> translations_dictionary
{'car': 'Auto', 'hat': 'Hut', 'house': 'Haus'}
We can achieve the same in a simpler way. We can pass the zip method as the argument of the method dict:
>>> dict(zip(english_words, german_words))
{'car': 'Auto', 'hat': 'Hut', 'house': 'Haus'}
Lists it Doesn’t Work For
It doesn’t work for all lists. The keys in a dictionary must be an immutable data type. So, if we have a mutable data type (like lists) in the first list, they can’t be converted to keys in the dictionary. We get an error:
>>> odd_triplets = [[1,3,5], [7, 9, 11]]
>>> middles = [3, 9]
>>> dict(zip(odd_triplets, middles))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
Lists with Different Numbers of Elements
And what happens if the numbers of elements in the two lists are different? The superfluous elements will be lost:
>>> positions = [1, 2, 3, 4, 5]
>>> rewards = ["gold medal", "silver medal", "bronze medal"]
The two superfluous positions 4 and 5 will be lost:
>>> dict(zip(positions, rewards))
{1: 'gold medal', 2: 'silver medal', 3: 'bronze medal'}
Iterators Get Used Up
There is one thing we have to know about the method zip. It returns an iterator, not a list. In iterators the elements get used up, so that they can’t be used again. Here we have two lists:
>>> seas = ["Baltic Sea", "Sea of Japan", "Arabian Sea"]
>>> oceans = ["Atlantic Ocean", "Pacific Ocean", "Indian Ocean"]
Let’s zip them:
>>> seas_iterator = zip(seas, oceans)
Let’s use the iterator to make a list:
>>> sea_list1 = list(seas_iterator)
Let’s make another list using the same iterator:
>>> sea_list2 = list(seas_iterator)
The iterator gets used up when it is used in the first list, so the elements go to the first list:
>>> sea_list1
[('Baltic Sea', 'Atlantic Ocean'), ('Sea of Japan', 'Pacific Ocean'), ('Arabian Sea', 'Indian Ocean')]
and there is nothing left for the second list. The second list is empty:
>>> sea_list2
[]