02 CDT - 10 Dictinaries Practice Questions

Accessing Dictionary items

>>> students
{'Hermione': 'Gryffindor', 
'Harry': 'Gryffindor', 
'Ron': 'Gryffindor', 
'Draco': 'Slytherin'}

>>> students['Hermione']
'Gryffindor'
>>> students['Draco']
'Slytherin'

Accessing the key values

>>> for student in students:
...     print(student)
... 
Hermione
Harry
Ron
Draco

Accessing values using keys

>>> for student in students:
...     print( student, students[student], sep=", ")
... 
Hermione, Gryffindor
Harry, Gryffindor
Ron, Gryffindor
Draco, Slytherin

students[student] is using the name as key to get the associated value, which could also have been gotten by using items() or values()


A List of Dictionaries

Keyword “None” with capital N, which represents absence of value, All dict{} are given same key words but different values, by design keys are standardized to find things easily.

>>> students = [
    {"name": "Hermione", "house": "Gryffindor", "patronus":"Otter" },
    {"name": "Harry", "house": "Gryffindor", "patronus": "Stag" },
    {"name": "Ron", "house": "Gryffindor", "patronus": "Terrier" },
    {"name": "Draco", "house": "Slytherin", "patronus": None}
]

>>> for student in students:
...     print(student["name"], student["house"], student["patronus"], sep=", ")
... 
Hermione, Gryffindor, Otter
Harry, Gryffindor, Stag
Ron, Gryffindor, Terrier
Draco, Slytherin, None

print(student["name"]) will get the value of key word “name”


Looping through Dictionary Elements in a list

>>> students =[ {"name":"Hermione","house":"Gryffindor","patronus":"Otter"},{"name":"Harry","house":"Gryffindor","patronus":"Stag"},{"name":"Ron","house":"Gryffindor","patronus":"Terrier"},{"name":"Draco","house":"Slytherin","patronus":None} ]

>>> students.values()
AttributeError: 'list' object has no attribute 'values'
# Here students is a list[] so values do not work directly

Using loop to access the nested dictionaries and applying values()

>>> for student in students:
...     print(student.values())
... 
dict_values(['Hermione', 'Gryffindor', 'Otter'])
dict_values(['Harry', 'Gryffindor', 'Stag'])
dict_values(['Ron', 'Gryffindor', 'Terrier'])
dict_values(['Draco', 'Slytherin', None])
>>> for student in students:
...     print(student.keys())
... 
dict_keys(['name', 'house', 'patronus'])
dict_keys(['name', 'house', 'patronus'])
dict_keys(['name', 'house', 'patronus'])
dict_keys(['name', 'house', 'patronus'])
>>> for student in students:
...     print(student.items())
... 
dict_items([('name', 'Hermione'), ('house', 'Gryffindor'), ('patronus', 'Otter')])
dict_items([('name', 'Harry'), ('house', 'Gryffindor'), ('patronus', 'Stag')])
dict_items([('name', 'Ron'), ('house', 'Gryffindor'), ('patronus', 'Terrier')])
dict_items([('name', 'Draco'), ('house', 'Slytherin'), ('patronus', None)])

Converting a string into dictionary key values

>>> str = "Vijay=23,Ganesh=20,Lakshmi=19,Nikhil=22"
>>> lst = []
>>> for x in str.split(","):
...     y = x.split("=")
...     lst.append(y)
... 
>>> lst   # all are strings
[['Vijay', '23'], ['Ganesh', '20'], ['Lakshmi', '19'], ['Nikhil', '22']]
# converting to dictionary
>>> temp_dic = dict(lst)
>>> temp_dic
{'Vijay': '23', 'Ganesh': '20', 'Lakshmi': '19', 'Nikhil': '22'}
# convering to int
>>> a_dict = {}
>>> for key, value in temp_dic.items():
...     a_dict[key] = int(value)
... 
>>> a_dict
{'Vijay': 23, 'Ganesh': 20, 'Lakshmi': 19, 'Nikhil': 22}

To find the number of occurrences of each letter in a string.

>>> str = "Book Store is open"
>>> dict = {}
>>> for x in str:
...     dict[x] = dict.get(x, 0)+1
... 
>>> for key, value in dict.items():
...     print( f"Key: {key} has appeared {value} times." )
... 
Key: B has appeared 1 times.
Key: o has appeared 4 times.
Key: k has appeared 1 times.
Key:   has appeared 3 times.
Key: S has appeared 1 times.
Key: t has appeared 1 times.
Key: r has appeared 1 times.
Key: e has appeared 2 times.
Key: i has appeared 1 times.
Key: s has appeared 1 times.
Key: p has appeared 1 times.
Key: n has appeared 1 times.

The loop tries to get the characters value, if not found then default is 0. It will create a new key and assigns 0 to that.

If get returns a value, then 1 is added to it and re assigned to the key (overwriting previous key which was same letter).


To find the largest Key and value from a dictionary

>>> count = { 'apple' : 10, "banana" : 5, "orange":15, "grapes":20 }

>>> max_key = ""
>>> for fruit in count:
...     if fruit > max_key:
...             max_key = fruit
...             max_value = count[fruit]
... 
>>> print("Max key: ", max_key)
Max key:  orange
>>> print("Max value: ", max_value)
Max value:  15

>>> 12 in count
False
>>> 10 in count
False
>>> 10 in count.values()
True

>>> values = list(count.values())
>>> values.sort( reverse=True )
>>> values
[20, 15, 10, 5]

>>> "Second largest value: ", values[1]
('Second largest value: ', 15)

Making an empty list and populating it

Using range() to create a fleet of 30 aliens

aliens = []
for ali in range(30):
    new_alien = {"colour":"green", "points": "5", "speed":"slow" }
    aliens.append(new_alien)

Making 3 alien in the list change color, speed and points. Looping through only 3 and then changing all values for the keys

for a in aliens[:3]:
    if a["colour"] == "green":
        a["colour"] = "yellow"
        a["speed"] = "medium"
        a["points"] = 10

# to make any yellow aliens to red,
    elif a["colour"] == "yelow":
        a["colour"] = "red"
        a["speed"] = "fast"
        a["points"] = 15
for ali in aliens:
    print(ali)

A list inside a dictionary

Pizza order

>>> print(f"You have ordered a {pizza['crust']} crust pizza. \nWith the following toppings: ")
 
>>> for top in pizza["toppings"]:
...     print(f"\t{top}")
... 
You have ordered a thick crust pizza. 
With the following toppings:
	mushroom
	extra cheese

Finding Favorite language from list within a Dictionary

fav_lang.values() will not work because it is a list. so list iteration.

>>> fav_lang={'jen':['python','rust'],'sarah': ['c'],
... 'edward': ['rust', 'go'],'phil': ['python', 'haskell']}

>>> for name in fav_lang:
...     print(f"{name}'s favorite languages are: ")
...     for lang in fav_lang[name]:
...             print(f"\t{lang}")
... 
jen's favorite languages are: 
	python
	rust
sarah's favorite languages are: 
	c
edward's favorite languages are: 
	rust
	go
phil's favorite languages are: 
	python
	haskell

Could be somewhat simplified with items()

>>> for name, lang in fav_lang.items():
...     print(f"{name}'s favorite values are: ")
...     for each in lang:
...             print(f"\t{each}")
... 
jen's favorite values are: 
	python
	rust
sarah's favorite values are: 
	c
edward's favorite values are: 
	rust
	go
phil's favorite values are: 
	python
	haskell

Refining to handle the singular and plural grammar issue

>>> for name, lang in fav_lang.items():
...     if len(lang) == 1:
...             print(f"{name.title()}'s favorite language is: ")
...             print(f"\t{lang[0].title()}")
...     else:
...             print(f"{name.title()}'s favorite languages are:")
...             for each in lang:
...                     print(f"\t{each.title()}")
... 
Jen's favorite languages are:
	Python
	Rust
Sarah's favorite language is: 
	C
Edward's favorite languages are:
	Rust
	Go
Phil's favorite languages are:
	Python
	Haskell

A dictionary in dictionary

>>> users={ 
'einstein':{'first':'albert','last':'einstein','location':'princeton',},
'mcurie':
{'first':'marie','last':'curie','location':'paris',}
}

>>> for user, data in users.items():
...     print( f"\nUsername: {user}")
...     print( f"\tFull Name: { data['first'].title()} {data['last'].title()}")
...     print( f"\tLocation: { data['location'].title()}")
... 

Username: einstein
	Full Name: Albert Einstein
	Location: Princeton

Username: mcurie
	Full Name: Marie Curie
	Location: Paris

Better to create two variable before passing to print.

>>> for user, data in users.items():
...     print( f"\nUsername: {user}")
...     full_name = f"{ data['first'].title()} {data['last'].title()}"
...     location = f"{data['location'].title()}"
...     print( f"\tFull Name: {full_name}\n\tLocation: {location}")
... 

Username: einstein
	Full Name: Albert Einstein
	Location: Princeton

Username: mcurie
	Full Name: Marie Curie
	Location: Paris

Sorting Dictionary elements using lambda function

>>> colors = { 10: "Red", 35: "Green", 15: "Blue", 25: "White" }

# Sorting by 0th element
>>> c1 = sorted(colors.items(), key = lambda t : t[0])
>>> c1
[(10, 'Red'), (15, 'Blue'), (25, 'White'), (35, 'Green')]

# Sorting by 1st element
>>> c1 = sorted(colors.items(), key = lambda t : t[1])
>>> c1
[(15, 'Blue'), (35, 'Green'), (10, 'Red'), (25, 'White')]

Dictionary Implementation as a Hash Table

A dictionary is implemented as a hash table, which consists of:

  • An array plus a hash function.

Underlying Storage: The Array

  • The underlying storage for the dictionary is an array.
  • Given an offset i , the element A[i] can be accessed in constant time.

Keys Mapping

  • Keys need to be mapped to the set {0,1,…,n−1}{0, 1, \dots, n-1}.
  • Given a key kk, we convert it to an offset i using the hash function.

Hash Function

A hash function h:S→X maps a set of values SS to a small range of integers X={0,1,…,n−1}

  • Typically, ∣X∣≪∣S∣ meaning there will be collisions (i.e., h(s)=h(s′) where s≠s′

Characteristics of a Good Hash Function:

  • A good hash function will minimize the number of collisions, which is important for efficiency and correctness.
  • SHA-256 is an industry-standard hashing function whose output is 256 bits long.
  • It is commonly used to hash large files due to its security and efficiency.