python:一种在嵌套字典中获取详尽,有序的键列表的方法吗?

sai*_*ale 3 python dictionary

详尽无遗:
- 字典中的所有键,即使键位于嵌套字典中,该字典是前一级字典键的值.

已排序:
- 这是为了确保始终以相同的顺序返回键

嵌套是任意深度的.非递归算法是优选的.

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'}]}

Ale*_*lli 6

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)