【问题标题】:Get list of all sub-keys from a python dictionary从 python 字典中获取所有子键的列表
【发布时间】:2019-08-09 21:49:53
【问题描述】:

我有一些字典(json 输出)。我想获取可以是字符串列表或字符串的基本元素。目前我正在这样做:-

folder="shared/"
files=os.listdir('shared')


for f in files:
    f=folder+f
    print(f)
    with open(f) as f:
        data = json.load(f)
    #data is a dict now with sub-keys
    for key,value in data.items():
        if value.keys():
            print(value)
    break

这是python代码读取的输入字典:-

{
  "shortshirt": {
    "ralphlauren": {
      "classic": [
        "That Ralph Lauren classic fit is a timeless look!",
        "Nice choice. Can’t go wrong with Ralph Lauren"
      ]
    }
  },
  "socks": {
    "": {
      "": ["Have to find the right socks to keep your feet cozy"]
    }
  }
}

这是我得到的输出:-

{'ralphlauren': {'classic': ['That Ralph Lauren classic fit is a timeless look!', 'Nice choice. Can’t go wrong with Ralph Lauren']}}
{'': {'': ['Have to find the right socks to keep your feet cozy']}}

但这就是我想要的:-

keys=[["shortshirt","ralphlauren","classic"],["socks"]]

value=[['That Ralph Lauren classic fit is a timeless look!', 'Nice choice. Can’t go wrong with Ralph Lauren'], ['Have to find the right socks to keep your feet cozy']]

但我不知道是有 2 级还是 3 级嵌套循环。如果我有一个内部循环并且实际上没有嵌套键,那么我会得到值错误。我想在一个单独的列表中获取所有嵌套键,并在另一个列表中获取最低级别的一个或多个基本值,对此的任何帮助将不胜感激。

【问题讨论】:

  • 您的描述不清楚。为您的示例数据提供相应的预期输出。
  • 我已经编辑了问题。
  • 嗯,这是因为您没有在字典中查找,所以您只获取顶级值(即字典)。对于你想要的,你必须去字典,直到值不是字典。你可以递归地做到这一点。键也是一样的,不要忘记过滤空的。
  • 如果我下去(添加一个循环)那么我怎么知道我应该去多深?就像我的意思是,我要先写代码,如果我写了 3 个循环并且实际有 5 个子键,我将如何获得这些?
  • 递归,正如@JavierPazSedano 提到的,那么存在多少子键并不重要

标签: python dictionary recursion nested depth-first-search


【解决方案1】:

生成器对于这个问题很有用。策略——

  • Keys:跟踪当前的递归路径。一碰到树叶就让出当前路径。

  • 值:只产生叶子。

代码:

def getitems(obj):

  def getkeys(obj, stack):
    for k, v in obj.items():
      k2 = ([k] if k else []) + stack # don't return empty keys
      if v and isinstance(v, dict):
        for c in getkeys(v, k2):
          yield c
      else: # leaf
        yield k2

  def getvalues(obj):
    for v in obj.values():
      if not v: continue
      if isinstance(v, dict):
        for c in getvalues(v):
          yield c
      else: # leaf
        yield v if isinstance(v, list) else [v]

  return list(getkeys(obj,[])), list(getvalues(obj))

输入:

{
  "shortshirt": {
    "ralphlauren": {
      "classic": [
        "That Ralph Lauren classic fit is a timeless look!",
        "Nice choice. Can't go wrong with Ralph Lauren"
      ]
    }
  },
  "socks": {
    "": {
      "": ["Have to find the right socks to keep your feet cozy"]
    }
  }
}

输出:

# keys
[['classic', 'ralphlauren', 'shortshirt'], ['socks']]

# values
[['That Ralph Lauren classic fit is a timeless look!', "Nice choice. Can't go wrong with Ralph Lauren"], ['Have to find the right socks to keep your feet cozy']]

【讨论】:

    猜你喜欢
    • 2022-08-14
    • 1970-01-01
    • 2014-11-27
    • 2016-05-27
    • 2020-10-13
    • 2016-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多