If you need to use the whole combination of key1
to keyn
to get value
, you can flip the dict like I suggested below for O(nk*nv) (number of keys * number of values) or use the tuple
method above.
Assuming you need to build the tuple
on insertion and again when you need to get a value, both will be O(nk) where nk
is the number of keys.
The nested dict
version might be more space efficient if you're nested fairly deeply (there are lots of values that share a partial ordered list of keys), and getting a value will still be O(nk), but probably slower than the tuple version.
However, insertion will be slower, though I can't quantify it's speed. You will have to construct at least one layer of dict
for each insertion, and test for the existence of
dict
s at the previous levels.
There are many recipes for recursive defaultdict
s that would simplify insertion from a coding perspective, but it wouldn't actually speed things up.
The tuple
method is both simpler and faster for insertion, but may take more memory depending on your nesting.
Original answer from before I knew the requirements
Why not
{'key1' : 'value', 'key2' : 'value', .... 'keyn' : 'value' }
It's just storing a reference to value
at each location, not value
itself, so the memory usage would be less than the nested dict
version, and not much larger than the tuple
version, unless you have an extremely large number of value
s.
For time complexity of Python standard type operations, see the Python wiki.
Basically, insertion or getting one item on average is O(1).
Getting all the keys for a value would on average be O(n):
[key for key in mydict if mydict[key] == value]
However, if adding keys, or searching for all keys, is the usual operation, your dict
is flipped. You want:
{'value': [key1, key2, ... keyn]}
This way you can add keys with just mydict[value].append(newkey)
and get all the keys with just mydict[value]
and both will be on average O(1).