我不知道你为什么要这样做,当数据结构大小增加时,这种事情会变得很慢。有一个平面字典可能会更好,但是必须定义展平算法。
我已经为我认为你想要的做了一些粗暴的事情。该flatten
方法返回类似于items
((键,值)元组的列表),其中“键”实际上是键的元组。这是必要的,因为字典可能包含相同的键,因此当转换到平面名称空间(需要唯一键)时,就会出现冲突。
class recurdict(dict):
'''
Recursive Dictionary
'''
def __init__(self, idict=None, **kwargs):
dict.__init__(self)
if idict is not None:
self.update(idict)
if len(kwargs):
self.update(kwargs)
def __contains__(self, key):
return (key in self.keys())
def __getitem__(self, key):
if self.__contains__(key):
return self.___getitem__(self, key)
else:
raise KeyError(key)
@staticmethod
def ___getitem__(idict, key):
if dict.__contains__(idict, key):
return dict.__getitem__(idict, key)
else:
result = None
for k, v in idict.iteritems():
if hasattr(v, "keys"):
result = recurdict.___getitem__(v, key)
if(result):
return result
else:
continue
def flatten(self):
return self._flatten(self)
@staticmethod
def _flatten(idict, key_chain = []):
found_keys = []
for k, v in idict.iteritems():
if hasattr(v, "keys"):
found_keys.extend(recurdict._flatten(v, key_chain + [k]))
else:
found_keys.append((tuple(key_chain + [k]), v))
return found_keys
def has_key(self, key):
return self.__contains__(key)
def keys(self):
return self._keys(self)
@staticmethod
def _keys(idict):
found_keys = dict.keys(idict)
for k, v in idict.iteritems():
if hasattr(v, "keys"):
found_keys.extend(recurdict._keys(v))
return found_keys
def update(self, other=None, **kwargs):
if other is None:
pass
elif hasattr(other, "iteritems"):
for k, v in other.iteritems():
self.__setitem__(k,v)
elif hasattr(other, "keys"):
for k in other.keys():
self.__setitem__(k,other.__getitem__(k))
else:
for k, v in other:
self.__setitem__(k,v)
if kwargs:
self.update(kwargs)
example_dict = recurdict\
({
"key1" : "value1",
"key2" : "value2",
"key3" :
{
"key3a": "value3a"
},
"key4" :
{
"key4a":
{
"key4aa": "value4aa",
"key4ab": "value4ab",
"key4ac":
{
"key4ac1": [0,1,2],
"key4ac2": (3,4,5),
"key4ac3":
[
{
"sub_key_x": 0,
"sub_key_y": 1,
},
6
]
}
},
"key4b": "value4b"
}
})
print example_dict.keys()
print "key1" in example_dict
print "key4ac1" in example_dict
print example_dict["key4ac1"]
for (k, v) in example_dict.flatten():
print (k, v)