# Python complex dictionary keys

My question pertains to dictionary keys. I want to set up a dictionary that has 3 keys for any single object. The keys must be in order and can have a wide range of values. For instance,

dictionary = {(key1,key2,key3) : object}

key1 can be any value between 1 and 10 key2 can be any value between 11 and 20 key3 can be any value between 21 and 30

The order in which the keys are placed does matter.

More specifically, my keys correspond to a range of x,y,z cartesian coordinates in which many objects are floating around in. I want to be able to sort the relative position of the objects based off their x,y,z positions.

Is there any way to set this up or will I have to take a different approach? Thanks for any help!

## Answers

Sure you can, as well as to create single string key for this - just merge string results for your keys like ','.join([k1,k2,k3])

dictionaries are indexed by keys, which can be any immutable type; strings and numbers can always be keys. Tuples can be used as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key. You canâ€™t use lists as keys, since lists can be modified in place using index assignments, slice assignments, or methods like append() and extend().

So you trying to use tuples as a keys and this is OK.

Note that dictionaries in python are not sorted. You can use collections.OrderedDict for this. Also to build correct sorting use sort/sorted functions with parameter key specified to sort the way you want.

EDITED sample:

from itertools import product myDict = {} for x,y,z in product(range(10), range(10,20), range(20,30)): myDict[(x,y,z)] = sum([x,y,z])

Hopefully you will find this useful.

>>> from math import sqrt >>> def dist(p1, p2): ... x1, y1, z1 = p1 ... x2, y2, z2 = p2 ... xd = x1 - x2 ... yd = y1 - y2 ... zd = z1 - z2 ... return sqrt((xd ** 2 + yd ** 2 + zd ** 2)) >>> myPoint = (0,0,0) >>> class MyObject: pass >>> myDict = {(1,2,3):MyObject(), (4,5,6):MyObject()} >>> sorted([dist(myPoint, point) for point in myDict]) 10: [3.7416573867739413, 8.774964387392123]

It seems to me that you want a possibly unordered collection of mappings from keys (ordered triples) to values (objects). If that's the case, it's very easy to make a composite key out of an ordered triple:

Suppose obj0 is at x,y,z coordinates (10,20,30) and obj1 is at x,y,z coordinates (11,21,31). Then:

myObjects = {(10,20,30): obj0, (11,21,31): obj1 }

This works because both tuples and ints are immutable types

Hope that helps