Dictionaries (Maps)

All of the compound data types we have studied in detail so far — strings, lists, and tuples — are sequential collections. This means that the items in the collection are ordered from left to right and they use integers as indices to access the values they contain.

Dictionaries are a different kind of collection. They are Python’s built-in mapping type. A map is an unordered, associative collection.

8.1 Dictionaries

It is easier to think of a dictionary as an unordered set of a comma-separated list of key:value pairs within the braces {}, each key and it's corresponding value are separated by a colon, key:value pair is the element of a dict, like:

dict = { key1: value1, key2: value2}

Dictionary values can be any datatype, including strings, integers, objects, or even other dictionaries. And within a single dictionary, the values don't all need to be the same type; you can mix and match as needed.

Dictionary keys are more restricted, which can be any immutable type; strings and numbers can always be keys. You can’t use lists as keys, since lists can be modified You can also mix and match key datatypes within a dictionary.

  • Empty dictionary, {}
  • Keys must always be unique within one dict, no duplicate keys in a dictionary
  • Dictionary keys are case-sensitive
  • Dictionaries have no concept of order among elements
  • Dictionaries are indexed by keys using dict[key], we can access key value this way.
  • It is an error to extract a value using a non-existent key.

Ex, 8.1-1 some_dict.py

# some_dict.py
>>> a_dict = {'a':3, 'b': 5, 'M': 8}
>>> a_dict['b']      # access value by keys
5
>>>
>>> records={'name':'Teddy', 'ageYear':1.5, 'heightInch':10, 'eye':'Brown'}
>>>
>>> records['eye']       
Brown
>>>
>>> luggage ={'dress':2, 't-shirt':5, 'phone':1, 'shoes':4}
>>>
>>> luggage['shoes']
4

Like lists, dictionaries are mutable: we can add new key:value pairs or change key's value

dict[key] = value, assign value to a key

  • If the key was not in original dict, doing this will add new key:value pair to the dict;
  • Assigning a value to an existing dictionary key simply replaces the old value with a new value.

Ex. 8.1-2 change_dict.py

# change_dict.py
>>> fruits = { 'apple' : 2, 'banana' : 1, 'pear' : 6}

>>> fruits ['banana']    # use [key] to access value 
1
>>> fruits ['banana'] = 8    # Change the key value, the old value is replaced.
>>> fruits
{'apple' : 2, 'pear' : 6, 'banana' : 8}    
>>>
>>> fruits ['orange'] = 3    # Add keys and values, use a key rather than an index
>>> fruits
{'apple' : 2, 'pear': 6, 'banana' : 8, 'orange': 3}
>>>

Ex. 8.1-3 more_dict.py

# more_dict.py
>>>records={'name':'Teddy', 'ageYear':1.5, 'heightInch':10, 'eye':'Blue'} 
>>>
>>> records['eye']
Blue
>>> records['eye']='Black'  
>>> records['homeCountry'] = 'Imagine Land'
>>> print(records)
{'ageYear':1.5, 'name':'Teddy', 'homeCountry': 'Imagine Land', 'heightInch':10, 'eye':'Black'}  
>>>

We can guess, ways to make a new dictionary include:

Provide a list of key-value pairs using the dictionary syntax as: d={'one':'uno','two':'dos','three':'tres'}

Another way is to start with the empty dictionary and add key-value pairs.

>>> d= {}
>>> d['one'] = 'uno'
>>> d['two'] = 'dos'
>>> d['three'] = 'tres'
>>> print (d)
{'one':'uno','two':'dos','three':'tres'}

There are some other ways to create a dictionary, we will talk about those in Pro Topics later.

Note: Python doesn't keep the items in a dictionary in the order that you enter them, if you need items to be in a specific order, you should use a list.

8.2 Functions, Operations and Methods of Dictionaries

delete element key:value pair: del(dict[key])

Check membership: in and not in keywords

Find out the number of key/value pairs in a dictionary: len(d) function

Ex. 8.2-1 operate_dict.py

# operate_dict.py
>>> fruits = { 'apple' : 2, 'banana' : 1, 'pear' : 6}
>>> 'pear' in fruits
True
>>> if 'kiwi' not in fruits:
        fruits['kiwi'] = 0 
>>>
>>> fruits
{'banaba':1, 'apple':2, 'pear': 6, 'kiwi':0}        
>>>              # Note the order of elements may change
>>> fruits['kiwi'] += 10  # same as fruits['kiwi']=fruits['kiwi']+10
>>> del(fruits['pear'])
>>> fruits
{'banaba':8, 'apple':2, 'kiwi':10}     
>>> len(fruits)
3
>>>

Some useful dictionary methods:

d.keys() returns a view of the keys of d d.values() returns a view of the values of d d.pop(key) removes key and returns its corresponding value d.clear() removes all items from d

list(d.keys()) returns a list of all the keys used in the dictionary, in arbitrary order

sorted(d.keys()) will sort the keys in order

More examples: Ex 8.2-2 meth_dict.py

# meth_dict.py
>>> kids_sports={'Emma':'Swimming', 'Frank':'Baseball', 'Helen':'Cross Country'}
>>> kids_sports.pop('Emma')
Swimming  
>>> kids_sports
{'Helen': 'Cross Country', 'Frank':'Baseball'}
>>>
>>>kids_sports['Mike']= 'Basketball'
>>>
>>>'Hedi' in kids_sports
False
>>> kids_sports['Hedi'] = 'Baseball'
>>>
>>> list(kids_sports.keys())
['Frank', 'Mike', 'Helen', 'Hedi']
>>> sorted(kids_sports.keys())
['Frank', 'Hedi', 'Helen', 'Mike']  # keys are in order
>>> kids_sports.values()  # keys are unique, values are not
['Baseball', 'Cross Country', 'Baseball', 'Basketball']
>>>
>>> kids_sports.clear()
>>> kids_sports
{}        # All empty!
>>>

Be aware of Dictionary Aliasing Using d.copy()

Because dictionaries are mutable, you need to be aware of aliasing(as we saw with lists). Whenever two variables refer to the same dictionary object, changes to one affect the other. If you want to keep the origingal dict, make a copy using d.copy() method, the copy is a new dictionary, so make change to it won't affect the original.

Ex. 8.2-3 dict_copy.py

# dict_copy.py
>>> records={'Math':90, 'Reading':85, 'Science':93}
>>> update = records  ' 
>>> print( update is records )
True       # both refer to the same dict object
>>> extraCredit = 10
>>> update['Reading'] += extraCredit
>>> print(update)
{'Math':90, 'Reading':95, 'Science':93}
>>>print( records)
{'Math':90, 'Reading':95, 'Science':93}   # both changed 
>>>
>>> update2 = records.copy()   # Make a new dict as a copy of the original
>>> update2['Reading'] += extraCredit
>>> update2['Reading']
95
>>> records['Reading']
85       # See? The original is unchanged!
>>>

8.3 Iterate over a dictionary

We can use for loop to iterate over the keys in a dictionary.

Ex. 8.3-1 loop_dictKeys.py

# loop_dictKeys.py

pets = {'Sara':'dog','Hanna':'fish','Hadi':'horse', 'Sam':'cat'}
print( pets.keys() )

for key in pets.keys():
    print( '{0} likes {1}'.format(key, pets[key]) )

... # run

dict_keys(['Hanna', 'Sara', 'Hadi', 'Sam'])
Hanna likes fish
Sara likes dog
Hedi likes horse
Sam likes cat

iterating over a dictionary implicitly iterates over its keys.

It is so common to iterate over the keys in a dictionary that you can omit the keys method call in the for loop in the above example.

Ex. 8.3-2 loop_dict.py

# loop_dict.py

pets = {'Sara':'dog','Hanna':'fish','Hadi':'horse', 'Sam':'cat'}

for k in pets:      # works the same as above example
    print( '{0} likes {1}'.format(k, pets[k]) )
... # run

Hanna likes fish
Sara likes dog
Hedi likes horse
Sam likes cat

When looping through dictionaries, the key and corresponding value can be retrieved at the same time using the items() method.

One more dict method to look at(more in Pro Topic): d.items() Returns a view of the key-value pairs in the dictionary. Note that the items are shown as tuples containing the key and the associated value.

Ex. 8.3-3 loop_item.py

# loop_item.py

records={'Math':90, 'Reading':85, 'Science':93}

print( records.items() )

for k, v in records.items():
       print(k, v)
...#run

dict_items([('Math', 90), ('Science', 93), ('Reading', 85)])        # a list of tuples

Math 90
Science 93
Reading 85

Next example is a little bit complicate, pay close attention. I will use two dictionaries.

Ex. 8.3-4 loop_twoDicts.py

# loop_twoDicts.py

subjects= {'English':'ENG201', 'Spanish':'SP101', 'Computer Science':'CS322', 'Physics':'PH302'}

grades= {'PH302':90, 'CS322':95, 'SP101': 98, 'ENG201': 90}

print( grades[ subjects['Spanish'] ] )  # to get Spanish class grade

for s in subjects:
    print('{0} class number is {1}, grade is {2}'
     .format(s, subjects[s], grades[subjects[s]])

#run ...

98
Computer Science class number is CS322, grade is 95
Spanish class number is SP101, grade is 98
Physics class number is PH302, grade is 90
English class number is ENG201, grade is 90

8.4 Pro Topics

Dictionary methods

We've covered some commonly used dictionary methods in previous topics. Here is a more complete list of dictionary methods:

d.keys() returns a view of the keys d.values() returns a view of the values

d.pop(key) removes key and returns its value d.get(key) returns the value associated with key; if key is not in d, returns None

d.setdefault(key, v) if key is in d, returns its value; if not, adds new entry (key, v) to d, then returns it's value v

d.items() returns a view of the key-value pairs in the dictionary d.popitem() returns and removes some (key, value ) pair from d

d.update (e) adds the (key, value) pairs in e to dict d, e may be another dictionary or a sequence of pairs. d.clear() deletes all elements in d, so d will be an empty dict.

Ex. 8.4-1 more_meth.py

# more_meth.py
>>> records={'Math':90, 'Reading':85, 'Science':93}
>>> records.get( 'Math' )  # Original dict is unchanged
90
>>> records.keys()    
dict_keys(['Reading', 'Math', 'Science'])
>>>
>>> records.popitem()
('Science', 93)
>>> records.popitem()
('Math', 90)    # popitem() removes and returns a random pair from the dict
>>> records
{'Reading': 85}
>>>
>>> records['Bio'] = 80    # A new entry is added.
>>> records
{'Bio': 80, 'Reading': 85}
>>>
>>> records.update( {'Social Studies': 96} ) # A new entry is added.
>>> records
{'Bio': 80, 'Social Studies': 96, 'Reading': 85}
>>>
>>> records.setdefault('PE', 'pass')
pass
>>> records

{'Bio': 80, 'Social Studies': 96, 'PE': 'pass',  'Reading': 85}

Note, keys(), values(), items() all returns a view of keys, values or items(key/value pairs). Since the view is linked to original dictionary, when the original dict changed, so does the view.

Ex. 8.4-2 view_dict.py

# view_dict.py

>>> records={'Math':90, 'Reading':85, 'Science':93}
>>> k= records.keys()
>>> print (k)
dict_keys(['Math','Reading','Science'])
>>>
>>> records.pop('Science')
93
>>> print (k)
dict_keys(['Math','Reading'])
>>>

Create a dictionary

The basic ways to create a dictionary is to type in key:value pairs into a { }, separated by comma. Or make an empty dict, then add new entries (key:value pairs) to it.

Here we will talk about some other ways to make dictionaires:

dict() constructor The dict() constructor builds dictionaries directly from sequences of key-value pairs:

Ex. 8.4-3 dict_seq.py

# dict_seq.py
>>>
>>> dict([('chicks', 40), ('hens', 25), ('roosters', 2)])
{'chicks': 40, 'hens': 25, 'roosters': 2}

When the keys are simple strings, it is sometimes easier to specify pairs using keyword arguments:

Ex. 8.4-4 dict_str.py

# dict_str.py
>>>
>>> dict(cats=3, dogs=4, pigs=5)
{'cats':3, 'dogs':4, 'pigs':5}
>>># pay attention the right side of '=', is the assignment value, so it should match it's type.
>>> dict(cats='white', dogs='black', pigs='pink')
{'cats':'white', 'dogs':'black', 'pigs':'pink'}
>>>

Dictionary comprehension Similar to list comprehension, dict comprehensions can be used to create dictionaries from arbitrary key and value expressions:

Ex. 8.4-5 comprehen_dict.py

# comprehen_dict.py

>>> {x: x**3 for x in (2, 4, 6)}
{2: 8, 4: 64, 6: 216}

results matching ""

    No results matching ""