Вот класс, который использует defaultdict для автоматического вложения индексированных значений с некоторыми специальными __getitem__
и __setitem__
методами для приема кортежей в качестве аргументов:
from collections import defaultdict
defdict3level = (lambda : defaultdict(lambda :
defaultdict( lambda :
defaultdict(tuple))))
class dict3level(object):
def __init__(self):
self.defdict = defdict3level()
def __getitem__(self, key):
if isinstance(key, tuple):
if len(key)==3:
return self.defdict[key[0]][key[1]][key[2]]
elif len(key)==2:
return self.defdict[key[0]][key[1]]
elif len(key)==1:
return self.defdict[key[0]]
else:
return self.defdict[key]
def __setitem__(self, key, value):
if isinstance(key, tuple) and len(key)==3:
self.defdict[key[0]][key[1]][key[2]] = value
else:
self.defdict[key] = value
def __getattr__(self, attr):
return getattr(self.defdict, attr)
Теперь выполните все ваши задания, как раньше:
d = dict3level()
d[1,2,3] = (1,2,3,4)
d[1,2,7] = (3,4,5,6)
d[2,5,6] = (4,2,3,4,5,6)
Вы все еще можете получить определенную запись для определенного кортежа:
# get a specific entry
print d[1,2,3]
Но вы также можете перемещаться по уровням:
# get all different 0'th index values
print d.keys()
# get all sub values in d[1,2,*]
print d[1,2].keys()
for key in d[1,2]:
print "d[1,2,%d] = %s" % (key, d[1,2][key])
# no such entry, return empty tuple
print d[1,2,0]
Дает:
print d[1,2,3] -> (1, 2, 3, 4)
print d.keys() -> [1, 2]
print d[1,2].keys() -> [3, 7]
for key in d[1,2]:... ->
d[1,2,3] = (1, 2, 3, 4)
d[1,2,7] = (3, 4, 5, 6)
print d[1,2,0] -> ()
(Не знаю, как это повлияет на проблемы с памятью и / или травлением, но полученная структура имеет гораздо больше возможностей.)