Python Dictionary

Python Dictionary


  Machine Learning in Python

Summary : While lists are the most used data structure in Python, a dictionary is probably the second most useful data structure in Python. A dictionary is similar to a hash table, if you are familiar with other programming languages or data structures in general. A hash table has keys that can be used to retrieve values . This key-valuecombination is what a dictionary is all about.

Contents

What is Dictionary

Dictionaries are used to represent key value pairs. For example, the grades of a student in a class could be represented like this.

grades = { "Math"        : 4,
           "Physics"     : 3.8,
           "Chemistry"   : 3.6,
           "English"     : 3.7}
 grades

{'Math': 4, 'Physics': 3.8, 'Chemistry': 3.6, 'English': 3.7}

Creating an empty dictionary is just as simple.

# Create an empty dictionary
grades = {}
# OR
# Initialize a dictionary
grades = { "Math"        : 4,
           "Physics"     : 3.8,
           "Chemistry"   : 3.6,
           "English"     : 3.7}
{'Math': 4, 'Physics': 3.8, 'Chemistry': 3.6, 'English': 3.7}
grades
{'Math': 4, 'Physics': 3.8, 'Chemistry': 3.6, 'English': 3.7}

You can get the values for any of the keys using the square brackets notation. For example, you can get the Math grade as follows

print ( "My Math grade is ", grades["Math"])

My Math grade is  4

Unique keys

Python dictionaries are more or less equal to hash tables if you know them from other languages. So, naturally the key has to be unique. If the key is already present, it will update the value for that key

grades["Math"] = 3.9
grades

{'Math': 3.9, 'Physics': 3.8, 'Chemistry': 3.6, 'English': 3.7}

If the key does not exist, it gets added

grades["Biology"] = 3.5
grades

{'Math': 4, 'Physics': 3.8, 'Chemistry': 3.6, 'English': 3.7, 'Biology': 3.5}

grades = { "Math"        : 4,
           "Physics"     : 3.8,
           "Chemistry"   : 3.6,
           "English"     : 3.7}

print ( grades["Zoology"] )
Question : what is the result of the code above ?
Prints nothing
error

Get method

If you specifically want to the get the value of a particular key ( without over-riding the value), use the get method

grades.get("English")
3.7

This returns None if the key does not exist.

print ( grades.get("zoology") )
None

get vs index methods

What is the difference between the dict.get(key) and dict[key] ? The difference lies in the way Python reacts when the key is NOT present in the dictionary. For example, if the value is key is not present, the get ( ) method returns None

value = grades.get("Zoology") 
print ( value )
None

However, the index method returns an exception.

value = grades["Zoology"] 
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-4-5e3dc16cd99f> in <module>
----> 1 d["Chemistry"]

KeyError: 'Chemistry'

Vowels program

Challenge – Previously, while learning about lists, we have counted the number of vowels in a sentence. In this program, we will count the occurrence of each of the vowels.

For example, the sentence how are you has the following vowels
o – 2
e – 1
u – 1
a – 1
We could have very well done this using lists, how dictionary lend themselves better to this logic because, the vowels are unique and you don’t have to do lists of lists. Instead you can use the vowels for the keys and the counts for the values. In this program, we will be learning

– How to get initialize a dictionary
– How to insert a key,value pair
– How to check if a key exists

code
sentence = input ( "Enter a sentence -")

vowels = ['a','e','i','o','u']
vowel_count = {}

for i in list(sentence) :
    if i in vowels :
        if vowel_count.get(i) == None :
                # key doesn't exist yet. add it
                vowel_count[i] = 1
        else :
                # key already exist. add to the value
                vowel_count[i] = vowel_count[i] + 1

print ( vowel_count )

Key Order

The key is not ordered. Meaning, you cannot refer to values in a dictionary via an index. For example, this will given a key error.

grades[0]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-10-b0ec7979780f> in <module>
----> 1 grades[0]
KeyError: 0


Iterate over the dictionary

Since the keys are not ordered, there is no way you can use indexing to iterate dictionaries ( like you can do lists). However, Python provides simple for loop based iteration that provides keys in the dictionary. Inside the for loop, you can then access the value in the dictionary, based on the key.

grades = { "Math"        : 4,
           "Physics"     : 3.8,
           "Chemistry"   : 3.6,
           "English"     : 3.7}
for key in grades : 
 print ( key , " " , grades[key])


Math   4
Physics   3.8
Chemistry   3.6
English   3.7

items function on the other hand returns a list of tuples. Each tuple can then be further broken down to yield the key and value.

for item in grades.items() : 
    print ( item[0] , " " , item[1])
Math   4
Physics   3.8
Chemistry   3.6
English   3.7

If you look closely though, items( ) function does not return a list. It instead returns a special object – dict_items that can be used very much like a list to iterate over it.

type(grades.items())
dict_items

Key and Value Objects

You can get keys and values as separate objects – not as lists, but as separate objects like we have seen before.  

Keys Object

You can get the list of keys in the dictionary, may be do some pre-processing and get the values.

keys = grades.keys()
 keys

dict_keys(['Math', 'Physics', 'Chemistry', 'English'])

This is not a List though – It is a dictionary view object. Think of it like a dynamic pointer to the dictionary keys. If the dictionary changes, this object changes as well. 

grades["Biology"] = 3.6
 keys

dict_keys(['Math', 'Physics', 'Chemistry', 'English', 'Biology'])

If you instead wanted a static copy of the keys, you can convert it to a list

keys_list = list(keys)
 keys_list

['Math', 'Physics', 'Chemistry', 'English', 'Biology']

Now, when you add more keys to the dictionary, it will not have any effect on the converted list object.

grades["Zoology"] = 3.6
keys_list
 
['Math', 'Physics', 'Chemistry', 'English', 'Biology']
keys
dict_keys(['Math', 'Physics', 'Chemistry', 'English', 'Biology', 'Zoology'])

# dictionary of student id and grade in a particular subject
grades = { 103    : 4,
           101    : 3.8,
           102    : 3.6,
           104    : 3.7}

print ( sorted(grades.keys()) ) 

Question : what is the result of the code above ?
dict_keys([103, 101, 102, 104])
[101, 102, 103, 104]

Values Object

Get just the values from the dictionary ( as opposed to the keys)

grades.values()


dict_values([4, 3.8, 3.6, 3.7])

Once again, this is not a list, but a dict_values object that dynamically changes with the dictionary. You can convert that to a list for static manipulation  


Add Dictionaries

You can add one dictionary to another ( also called merging dictionaries) using the update( )function

science_grades = { "Math"        : 4,
                   "Physics"     : 3.8,
                   "Chemistry"   : 3.6}
arts_grades =     { "English"     : 3.2,
                   "Art"         : 2.9,
                   "Drama"       : 3.0 }

science_grades.update(arts_grades)
science_grades

{'Math': 4,
 'Physics': 3.8,
 'Chemistry': 3.6,
 'English': 3.2,
 'Art': 2.9,
 'Drama': 3.0}

science_grades = { "Math"        : 4,
                   "Physics"     : 3.8,
                   "Chemistry"   : 3.6}
arts_grades =     {"Math"        : 3.9, 
                   "English"     : 3.2,
                   "Art"         : 2.9,
                   "Drama"       : 3.0 }
science_grades.update(arts_grades)
Question : What is the value of the key “Math” after the code is executed ?
4.0
3.9

Delete Data

There are a couple of options to delete entries in a dictionary. 
– del 
– pop 
– clear

Delete using del

Use the standard python keyword del to delete data from a dictionary.

grades = { "Math"        : 4,
           "Physics"     : 3.8,
           "Chemistry"   : 3.6,
           "English"     : 3.7}

For example, to delete the “Math” grade, use

# Using the del keyword
 del grades["Math"]
 grades

{'Physics': 3.8, 'Chemistry': 3.6, 'English': 3.7}

Pop elements

You can also use the pop method to delete entries from a dictionary.

# Using pop method
grades.pop("Physics")
grades


{'Chemistry': 3.6, 'English': 3.7}

What happens when you try to remove an element that does not exist ?

grades.pop("Physics")
grades.pop("Physics")
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-69-1b9cfad3b822> in <module>
----> 1 grades.pop("Physics")
KeyError: 'Physics'
del grades["Physics"]
del grades["Physics"]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-20-3ae72ea1e273> in <module>
----> 1 del grades["Physics"]
KeyError: 'Physics'

Clear all elements

As usual, to clear all the values from a dictionary use the clear( ) function.

grades = { "Math"        : 4,
           "Physics"     : 3.8,
           "Chemistry"   : 3.6,
           "English"     : 3.7}
 grades


{'Math': 4, 'Physics': 3.8, 'Chemistry': 3.6, 'English': 3.7}
grades.clear()
 grades

{}

Shallow copy

Shallow copy of grades

  • copy () function
grades = { "Math"        : 4,
           "Physics"     : 3.8,
           "Chemistry"   : 3.6,
           "English"     : 3.7}

grades_c = grades.copy()

print ( id(grades) )

print ( id(grades_c) )

107894464
107895664
grades["Biology"] = 3.5
print( grades )
print ( grades_c )

{'Math': 4, 'Physics': 3.8, 'Chemistry': 3.6, 'English': 3.7, 'Biology': 3.5}
{'Math': 4, 'Physics': 3.8, 'Chemistry': 3.6, 'English': 3.7}

= ( equal to ) operator returns a new reference ( like a pointer ) to the same data.

grades_new = grades
id( grades_new )

107894464
grades.clear()

id(grades)
107894464
id(grades_c)
107895664
id(grades_new)
73892512
grades
{}
grades_c
{'Math': 4, 'Physics': 3.8, 'Chemistry': 3.6, 'English': 3.7}
grades_new

{}

Challenges

Challenge : Given a sentence, find out the list of all words that contain a particular vowel. List the same against each of the vowel.

In this challenge, you will learn that the values in a dictionary can be another data structure – like a list.
solution
sentence = input ( "Enter a sentence -")
words    = sentence.split(" ")

vowels = ['a','e','i','o','u']
vowel_words = {}

for word in words :
    for letter in list(word) :
        if letter in vowels :
                if vowel_words.get(letter) == None :
                        vowel_words[letter] = [word]
                else :
                        vowel_words.get(letter).append(word)

print ( vowel_words )

Challenge : Remove duplicate elements from a list

Let the user enter a bunch of words. Store them in a list. The user could have entered duplicate words as well. Eliminate all the duplicate words in the list and print only the unique words.
solution
l = []
# Let the user enter some string
while True :
    i = input("-")
    if i == "e" or i == "exit" :
        break
    else :
        l.append(i)

# Print the user entered list of values
print (l)

# Convert the list to a set. This will eliminate all duplicates
# just due to the nature of a set
s = set(l)
print (s)




Challenge : Count the length of each of the unique words in a sentence and list them in decreasing order

Take a string from the user as input and split it up into words. Sort all the words and discard all duplicate words. Once you have the unique list of words, count the length of each of the words and list them in decreasing order of length.
solution
input_string = input ( "Enter your string - ")

# Split the string into words
words = input_string.split(" ")

# Get only the unique words
words = set(words)

# Initialize a word length ( as a dictionary)
word_count = {  }


# # Iterate through the words and start updating the word length counter
for word in words :

    # If a word is not already counted, add it to the counter
    if word_count.get(word) == None :
        word_count[word] = len(word)

# Dictionaries cannot be sorted. So, create a list of tuples or lists
t_word_count = []
for word in word_count.keys() :
    t_word_count.append( [ word, word_count.get(word) ] )

# The sort criteria is the word count
def sort_criteria(ls) :
    return ls[1]

# Now sort the list based on the inner list's word length
t_word_count.sort(key = sort_criteria)

# Default sorting order is Ascending. If you want descending, set reverse flag to True
# t_word_count.sort(key = sort_criteria, reverse = True)


# Print them out
for i in t_word_count :
    print (i[0],"----",i[1])


Challenge : Count the occurrences of each of the unique words in a sentence and list them in decreasing order

Take a string from the user as input and split it up into words. Once you have the unique list of words, count the number of occurrences of each of the word and list them in decreasing order of occurrence.
solution
input_string = input ( "Enter your string - ")

# Split the string into words
words = input_string.split(" ")

# Initialize a word length count ( as a dictionary)
word_length = {  }


# # Iterate through the words and start updating the word length counter
for word in words :

    # If a word is not already counted, add it to the counter
    if word_length.get(word) == None :
        word_length[word] = 1
    
    # if the word is already in the dictionary, increment the counter
    else :
        word_length[word] = word_length[word] + 1

# Dictionaries cannot be sorted. So, create a list of tuples or lists
l_word_length = []
for word in word_length.keys() :
    l_word_length.append( [ word, word_length.get(word) ] )

# The sort criteria is the word count
def sort_criteria(ls) :
    return ls[1]

# Now sort the list based on the inner list's word length
l_word_length.sort(key = sort_criteria, reverse = True )


# Print them out
for i in l_word_length :
    print( "{:>10} -- {:>10}".format(i[0], i[1]) )


Challenge : Count the number of occurrences of each of the words in a sentence.

Take a string from the user as input and split it up into words. Sort all the words and discard all duplicate words. Once you have the unique list of words, count how many times each of the word occurs in the sentence.
solution
input_string = input ( "Enter your string - ")

# Split the string into words
words = input_string.split(" ")

# Initialize a word counter ( as a dictionary)
word_count = {  }


# # Iterate through the words and start updating counts
for word in words :

    # If a word is not already counted, add it to the counter
    if word_count.get(word) == None :
        word_count[word] = 1
    # If already present, increment the word count
    else :
        word_count[word] = word_count[word] + 1

# Finally, print the counter
print ( word_count)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.