Data structures‎ > ‎Dictionary‎ > ‎

Multiple keys

Multi-key combinations to access values

a) Table/matrix representation using tupels

Tupels are 'hashable' objects and hence can be used as a key in python dictionaries.

`{(key_part_1, key_part_2): value}`

Example
`d={}`
`d[('Antje','place')]='Barcelona'`
`d[('Antje','year')]='1987'`
`d[('Mike','place')]='Berlin'`

`key=('Antje','year')`
`if key in d:`
`    print( d[key] )`
1987

# Problem: when key-pair does not exist: key error for missing entries
`print( d[('Mike','year')] )`
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: ('Mikes', 'year')

# Solution: provide values for all key-pairs (a), or use sparse nested dictionary (b)

b) Sparse matrix or tree-like representation using dict in dict

# Nested dictionaries in python

`from collections import defaultdict`
`d = defaultdict(dict)`

`d['Antje']['place']='Barcelona'`
`d['Antje']['year']='1987'`
defaultdict(<type 'dict'>, {'Antje': {'place': 'Barcelona', 'year': '1987'}})
`d['Mike']['place']='Berlin'`

# print if key pair exist
`keyA='Antje'`
`keyB='year'`
`if ( keyA in d ) & ( keyB in d[keyA] ): `
`    print( d[keyA][keyB] )`
1987

# key error for missing entried
`print( d['Mike']['year'] )`
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'year'

# use get, to print default value if second key ('year') is missing
`print( d['Mike'].get('year', 'NaN') )`
NaN

# check if both key's are present
`if 'year' in d.get('Antje', {}):`
`    print( d['Antje']['year'] )`

# check if second key is present

`if d['Antje'].``get('year', False): `
`    print( d['Antje']['year'] )`

# check if first key is present
`'Mike' in d`
True

# get all first level keys
`sorted(d.keys())`
['Antje', 'Mike']

# get second level keys of selected first level key 'Mike'
`sorted([ k for k in d['Mike'] ])`
['place']

# get all second level keys of all first level keys together (set comprehension)
`sorted(list({k2 for v in d.values() for k2 in v}))`
['place', 'year']

# get all entries (items) of a name
`name='Antje'`
`[ d[name][k] for k in d[name] ] `
['Barcelona/Spain', '1987']

# get all items for second level keys: 'place' or 'year' (NaN if key is missing)
`[ d[k].get('place', 'NaN') for k in d]`
['Barcelona', 'Berlin']
`[ d[k].get('year', 'NaN') for k in d]`
['1987', 'NaN']
# sorted unique list of items for second level key 'place'
`sorted(set([ d[k].get('place', 'NaN') for k in d]))`
['Barcelona', 'Berlin']

# get all keys with same value 'Berlin' in second key 'place' (get all people born in Berlin)
`[k for k in d.keys() if d[k].get('place', 'NaN') == 'Berlin']`
['Mike']

# get all keys for which the second key 'year' exist
`[k for k in d.keys() if d[k].get('year', False)]`
['Antje']

# exchange/replace key with value : place -> name mapping