详尽无遗:
- 字典中的所有键,即使键位于嵌套字典中,该字典是前一级字典键的值.
已排序:
- 这是为了确保始终以相同的顺序返回键
嵌套是任意深度的.非递归算法是优选的.
level1 = {
'a' : 'aaaa',
'level2_1' : {'b': 'bbbbb', 'level3': {'c': 'cccc', 'd': 'dddddd'} },
'level2_2' : { 'z': 'zzzzzzz' }
}
Run Code Online (Sandbox Code Playgroud)
注意:字典值可以包括列表(可以将字典作为元素),例如
tricky = {'category': [{'content': 'aaaaa'}, {'content': 'bbbbbb'}]}
def _auxallkeys(aset, adict):
aset.update(adict)
for d in adict.itervalues():
if isinstance(d, dict):
_auxallkeys(aset, d)
def allkeys(adict):
aset = set()
_auxallkeys(aset, adict)
return sorted(aset)
Run Code Online (Sandbox Code Playgroud)
是明显的(递归)解决方案.消除递归:
def allkeys(adict):
aset = set()
pending = [adict]
while pending:
d = pending.pop()
aset.update(d)
for dd in d.itervalues():
if isinstance(dd, dict):
pending.append(dd)
return sorted(aset)
Run Code Online (Sandbox Code Playgroud)
因为各种嵌套dicts的处理顺序对于此目的无关紧要.
编辑:OP评论抱怨如果dict没有嵌套,它不起作用,而是在列表中(我回答说它也可能在一个元组中,一个具有每个实例或每个类的属性的对象[也许]它的一个基类],一个架子,以及许多其他隐藏房子周围的方法的方法;-).如果OP将设法通过"嵌套"准确定义他的意思(显然与普通凡人适用于所讨论的词的意思不同),那么帮助他可能会更容易.同时,这里有一个版本,涵盖了列表(和元组,但不包括生成器,许多itertools类的实例,架子等等);
def allkeys(adict):
aset = set()
pending = [adict]
pendlis = []
def do_seq(seq):
for dd in seq:
if isinstance(dd, dict):
pending.append(dd)
elif isinstance(dd, (list, tuple)):
pendlis.append(dd)
while pending or pendlis:
while pending:
d = pending.pop()
aset.update(d)
do_seq(d.itervalues())
while pendlis:
l = pendlis.pop()
do_seq(l)
return sorted(aset)
Run Code Online (Sandbox Code Playgroud)