we've been using strings as dictionary keysso farbut we aren' limited to string keys it is common to use strings as keysespecially when we're storing data in dictionary to gather it together (instead of using an object with named propertiesbut we can also use tuplesnumbersor even objects we've defined ourselves as dictionary keys we can even use different types of keys in single dictionaryrandom_keys {random_keys["astring""somestringrandom_keys[ "anintegerrandom_keys[ "floats work toorandom_keys[("abc" )"so do tuplesclass anobjectdef __init__(selfavalue)self avalue avalue my_object anobject( random_keys[my_object"we can even store objectsmy_object avalue tryrandom_keys[[ , , ]"we can' store lists thoughexceptprint("unable to store list\ "for keyvalue in random_keys items()print("{has value {}format(keyvalue)this code shows several different types of keys we can supply to dictionary it also shows one type of object that cannot be used we've already used lists extensivelyand we'll be seeing many more details of them in the next section because lists can change at any time (by adding or removing itemsfor example)they cannot hash to specific value objects that are hashable basically have defined algorithm that converts the object into unique integer value for rapid lookup this hash is what is actually used to look up values in dictionary for examplestrings map to integers based on the characters in the stringwhile tuples combine hashes of the items inside the tuple any two objects that are somehow considered equal (like strings with the same characters or tuples with the same valuesshould have the same hash valueand the hash value for an object should never ever change listshowevercan have their contents changedwhich would change their hash value (two lists should only be equal if their contents are the samebecause of thisthey can' be used as dictionary keys for the same reasondictionaries cannot be used as keys into other dictionaries