Dictionaries

Dictionaries are one of the most versatile data structures in Python. They are used to store name-value pairs.

d = {"x": 1, "y": 2, "z": 3}
d
{'x': 1, 'y': 2, 'z': 3}
d['x']
1
d['x'] = 11
d
{'x': 11, 'y': 2, 'z': 3}

We can check if a key is present in a dictionary using the in operator.

'x' in d
True
'foo' in d
False
'foo' not in d
True

Dictionary Use Cases

There are two typical use cases for dictionaries.

  1. as a record
  2. as a lookup table

Dictionary as a record

person = {
    "name": "alice",
    "email": "alice@example.com",
    "phone": "12345"
}
person
{'name': 'alice', 'email': 'alice@example.com', 'phone': '12345'}
person['name']
'alice'
person['email']
'alice@example.com'

When using a dictionary as a record, we know all the possible keys at the time of writing code.

Dictionary as a lookup table

The other common use case for dictionary is to use it like a lookup table.

phone_numbers = {
    "alice": "12345",
    "bob": "23456"
}
phone_numbers["alice"]
'12345'

When using the dictionary as a lookup table, the keys are not known upfront.

In the above example, while we are using phone_numbers with only two names, more names could be added to the phone_numbers by other parts of the program.

Example: Greeting in multiple languages

Let’s write a function greet to greet a person in any language.

If we just have to greet in one language English, we could write it as:

def greet(name):
    print(f"Hello", name)
greet("Alice")
Hello Alice

Now, let’s add support for multiple languages. The function now takes the language as the second argument.

# greet v2
def greet(name, lang):
    if lang == "en": 
        print("Hello", name)
    elif lang == "hi":
        print("Namaste", name)
greet("Alice", "en")
Hello Alice
greet("Alice", "hi")
Namaste Alice

While this above implementation works for two languages, adding a new language requires changing code, which is not nice. Can we think of a way to move it outside that function?

prefixes = {
    "en": "Hello",
    "hi": "Namaste",
    "it": "Caiso",
}
def greet(name, lang):
    prefix = prefixes[lang]
    print(prefix, name)
greet("Alice", "it")
Caiso Alice

We can even go one step further and move the translations to a text file.

%%file greetings.txt
en Hello
hi Namaste
it Caio
fr Bonjour
ka Namastara
te Namsakaram
ta Vanakkam
Writing greetings.txt

And read the file and populate prefixes.

prefixes = {}
for line in open("greetings.txt"):
    lang, prefix = line.strip().split()
    prefixes[lang] = prefix
prefixes
{'en': 'Hello',
 'hi': 'Namaste',
 'it': 'Caio',
 'fr': 'Bonjour',
 'ka': 'Namastara',
 'te': 'Namsakaram',
 'ta': 'Vanakkam'}
def greet(name, lang):
    prefix = prefixes[lang]
    print(prefix, name)
greet("Alice", "te")
Namsakaram Alice

Creating Dictionaries

Dictionaries can be created either using literal dictionary syntax, or using the dict function, or using dictionary comprehensions.

d = {"x": 1, "y": 2}
d
{'x': 1, 'y': 2}
d = dict(x=1, y=2)

The dict function can be used to create new dictionary by combining an existing one and adding new entries or updating existing ones.

dict(d, z=3)
{'x': 1, 'y': 2, 'z': 3}
dict(d, x=10, z=3)
{'x': 10, 'y': 2, 'z': 3}

The dict function also takes pairs.

numbers = ["one", "two", "three"]
dict([(n, n.upper()) for n in numbers])
{'one': 'ONE', 'two': 'TWO', 'three': 'THREE'}

Common Operations on Dictionaries

The get, setdefault and update are the common methods used on dictionaries.

get

The get method takes two arguments, the key and a default value. If the key is presnt, it returns the corresponding value, if not - it returns the default value.

phone_numbers = {
    "alice": "12345",
    "bob": "23456"
}
phone_numbers.get("alice", "-")
'12345'
phone_numbers.get("dave", "-")
'-'

setdefault

The setdefault works like get, but also adds an entry to the dictionary when the key is missing.

d = {"x": 1, "y": 2}
d.get('z', 0)
0
d
{'x': 1, 'y': 2}

Notice that d is not modified when we call get. Let’s see what happens if we use setdefault instead of get.

d.setdefault('z', 0)
0
d
{'x': 1, 'y': 2, 'z': 0}

update

The update method can be used to update a dictionary with the contents of another dictionary.

d1 = {"x": 1, "y": 2}
d2 = {"x": 11, "z": 3}
d1.update(d2)
d1
{'x': 11, 'y': 2, 'z': 3}

Iterating over a dictionary

coming soon!

Dictionary Comprehensions

coming soon!

Example: Word Frequncy

%%file wordfreq.py
"""
coming soon!
"""
Writing wordfreq.py