In [68]:
from pprint import pprint # import pretty print function. Can be used instead of print function.
dict, (dictionary), Pythons workhorse to store data in away it can be lookup by key in an extremely fast way, because the keys are hashed
(transformed in an integer that allows fast lookup). They are everywhere in the Python core and readily available for use by you.
Looking up a value in a dict mydict
stored under a given key key
value = myDict[key]
adding a new value under a new key:
myDict[newKey] = newValue
A key can be anythign that is hashable, that is, a key must at leasat be immutable. Immutable objects are
A dict can be generated by specifying key
: value
pairs between braces:
In [69]:
pets1 = {'cat' : ['spooky', 'fat tail'],
'dog' : ['barky', 'Donald', 'Fikky'],
'horse' : ['duke','bishop', 'knight']}
In [71]:
pets1['cat']
Out[71]:
In [73]:
pprint(pets1)
In [45]:
print(pets1)
print()
pprint(pets1)
In [74]:
pets1['dog']
Out[74]:
In [78]:
pets1['horse'][2] # the second horse
Out[78]:
We could als make a dict that allows to use the name of the pet as a key and then get the kind of pet
In [82]:
pets2 = {'spooky' : 'cat', 'fat tail' : 'cat', 'barky' : 'dog', 'Donald' : 'dog', 'Fikky' : 'dog',
'duke' : 'horse','bishop' : 'horse', 'knight' : 'horse'}
In [84]:
pprint(pets2)
In [50]:
pprint(pets2) # pprint prints in a nicer formatted way
In [51]:
pets2['duke']
Out[51]:
In [52]:
pets2['Fikky']
Out[52]:
Dicts have methods. The most important of them are keys()
, values()
and items()
Iterable means, that the object can be used like in iterable
like in loops: for key in pets2.keys():
In [53]:
print(pets1.keys())
print(pets2.keys())
print()
print(pets1.values())
print(pets2.values())
print()
print(pets1.items())
print()
print(pets2.items())
In [93]:
pets1.keys()
pets1.values()
pets1.items()
Out[93]:
You see that these key objects look like lists but they are not. They are in fact immutable, which is necessary to guaranty the integrety of the dict. You can turn them into a list by passing them to the list()
function.
In [94]:
print(list(pets1.keys()))
print(list(pets1.values()))
print(list(pets1.items())) # This is a list of tuples.
You could also turn these dict_keys etc into tuples:
In [14]:
print(list(pets2.keys())) # list because surrounded by square brackets (= mutable)
print(tuple(pets2.keys())) # Tuple because surrounded by braces (= immutable)
The order in which the key-value pairs have been given to a dict has no meaning into the order in which these pairs are stored or to the order in which they are shown when the dict is printed. The order may be different for different computer systems and even python releases.
In [95]:
# The order does not matter, so the contents of these two dict are the same, the answer is True
{'dog' : 'barky', 'horse' : 'duke', 'cat' : 'fat tail'} == {'horse' : 'duke', 'cat' : 'fat tail', 'dog' : 'barky'}
Out[95]:
In [96]:
# This is not true for two lists with the same items but in different order
['dog', 'cat'] == ['cat', 'dog']
Out[96]:
In [17]:
# But is is true for a set:
{'dog', 'cat', 'horse'} == {'horse', 'dog', 'cat'}
Out[17]:
More advanced dicts would be dicts of dicts, that is a dict
of which value
is found by key1
while the value
itself consists of a dic
t from which values
can be looked up by key2
.
For instance, we may have a dict
with key1
the name of the animal and key2
specifying properties of that particular animal, so we may ask pet['duke']['age']
, pet['spooky']['color']
etc. For example
In [97]:
pet = {'duke' : {'kind' : 'horse', 'age': 11, 'color' : 'brown'},
'spooky' : {'kind': 'cat', 'age': 8, 'color': 'red'},
'barky' : {'kind' : 'dog', 'age': 3, 'color': 'black'},
'fat tail': {'kind' : 'cat', 'age' : 4, 'color': 'white'},
}
In [98]:
pet
Out[98]:
In [99]:
pet['duke']
Out[99]:
In [19]:
pet['duke']['age']
Out[19]:
In [100]:
pet['spooky']['color']
Out[100]:
In [101]:
pet['spooky'].keys()
Out[101]:
In [102]:
pet['spooky'].values()
Out[102]:
In [103]:
pet['spooky'].items()
Out[103]:
You can iterate over the dict, that is over its keys
printing the pet shows its keys
In [110]:
for p in pet: # is should be for p in pet.keys() but that is not needed.
print("My animal {} is {} years old".format(pet[p]['kind'], pet[p]['age']))
In [111]:
'duke' in pet # is 'duke' one of the pets? (this check the keys)
Out[111]:
In [27]:
for p in pet: # iterate over the keys of pet
print(pet[p]) # print the contents of pet[p], the pet with key p
#print(p['color'])
In [28]:
for p in pet.keys(): # same thing, using the keys explicitly, but this is not necessary `p in pet` is enough
print(pet[p]) # print the contents of pet[p], the pet with key p
Now ask a question, like, which pets have age less than 7 years?
In [114]:
age = 7
youngPets = [] # start with an empty list
for p in pet:
if pet[p]['age'] < age:
youngPets.append(p)
print(youngPets)
print()
print('The pets {} are all less than {} years old.'.format(youngPets, age))
We can generate this list also with a so-called list comprehension.
First generate a list of all pets in the dict using list comprehension:
In [115]:
[p for p in pet]
Out[115]:
Then add the age condition to filter out the younger pets:
In [118]:
[p for p in pet if pet[p]['age'] < age]
Out[118]:
Hence:
In [64]:
younPets = [p for p in pet if pet[p]['age']<age]
print('The pets {} are all less than {} years old.'.format(youngPets, age))
In conclusion, the entire cell with for loop is now replaced by a single list comprehension.
Dict comprehsions and set comprehensions will be used next in a more advanced example.
In [119]:
import pdb
import inspect
def myfunc(kind, beast, *args, **kwargs):
#pdb.set_trace()
print("What enters the function {} ?".format(inspect.stack()[0][3]))
print("Here it is:")
print(" kind = ", kind)
print(" beast = ", beast)
print(" args = ", args)
print(" kwargs = ", kwargs)
print()
print(("My " + "{} " + "{} " + "{} " + "to " + "{} " + "in " + "{} " + "{}.\n").
format(kind, beast, args[0], args[1], kwargs['where'], kwargs['when']))
myfunc('dear', 'dog', "loves", 'walk', speed='slowly', dist=2, where='the garden', when='tonight')
Explanation of inspect.stack()
hence
Example below:
In [66]:
top = inspect.stack()[0]
for s in top:
print(s)
In [67]:
import inspect
def foo():
print(inspect.stack()[0][3])
foo()
In [ ]: