【问题标题】:Returning keys nested dictionary with Python使用 Python 返回键嵌套字典
【发布时间】:2022-01-13 18:09:15
【问题描述】:

编辑:感谢@arzo 的收获

我有一个嵌套字典,结构如下:

{
"key1":"string",
"key2":[{"nestedkey":"nestedvalue"}],
"key3":[1,2,3],
"key4":[{"nestedlevel1key":[{"nestedlevel2key":"nestedlevel2value"}]}],
"key5": {},
"key6": {"regularkey": "regularvalue"},
"key7": 15
}

字典键可以包含在其中:

  1. 字符串
  2. 整数
  3. 字典列表
  4. 包含字典列表的字典列表
  5. 空字典
  6. 普通字典

问题陈述是优化一种可以处理返回字典中所有键的方法。我可以这样写:

def get_keys(dict_example):
    keys = []

    for k,v in dict_example.items():
        keys.append(k)
        if isinstance(v, dict):
            for k in v.keys():
                keys.append(k)
        if isinstance(v, list):
            if isinstance(v[0], dict):
                for k,v in v[0].items():
                    keys.append(k)
                    if isinstance(v, list) and isinstance(v[0], dict):
                        for k in v[0].keys():
                            keys.append(k) 
    return keys
         keys = get_keys(dict_example)

            
print(keys)

这会给我(不按特定顺序)键列表:

['key1', 'key2', 'nestedkey1', 'key3', 'key4', 'nestedlevel1key', 'nestedlevel2key', 'key5', 'key6', 'regularkey', 'key7']

但我不确定是否有一种优化方法可以简化以处理所有 6 个用例,这些用例也可以穿过阵列,不管有多少层。现在我对层数进行了启发式分析,但在这个数组中可能有更深的层需要考虑。

【问题讨论】:

  • regularkey 是不是不见了?
  • @arzo 哦,谢谢你。其实是不见了!这应该包含在其中,这需要在当前逻辑中添加另一个条件。

标签: python dictionary iteration


【解决方案1】:

它们只有两种情况需要处理:listdict 因为它们包含其他东西,然后使用递归

  • 对于dict:保留键,并搜索值
  • list:搜索值
def get_keys(item):
    keys = []
    if isinstance(item, dict):
        for k, v in item.items():
            keys.append(k)
            keys.extend(get_keys(v))
    elif isinstance(item, (list, tuple)):
        for x in item:
            keys.extend(get_keys(x))
    return keys

values = {
    "key1": "string", "key2": [{"nestedkey": "nestedvalue"}], "key3": [1, 2, 3],
    "key4": [{"nestedlevel1key": [{"nestedlevel2key": "nestedlevel2value"}]}],
    "key5": {}, "key6": {"regularkey": "regularvalue"},
}

keys = get_keys(values)
print(keys)
# ['key1', 'key2', 'nestedkey', 'key3', 'key4', 'nestedlevel1key', 'nestedlevel2key', 'key5', 'key6', 'regularkey']

【讨论】:

  • 谢谢@argo!这种方法对于找出每个键的级别是否也是最佳的?例如,“nestedlevel1key”在级别 1,“nestedlevel2key”在级别 2,以此类推
【解决方案2】:

您可以使用递归函数来解决这个问题,而不是大量的嵌套循环:

origDict = {
"key1":"string",
"key2":[{"nestedkey":"nestedvalue"}],
"key3":[1,2,3],
"key4":[{"nestedlevel1key":[{"nestedlevel2key":"nestedlevel2value"}]}],
"key5": {},
"key6": {"regularkey": "regularvalue"},
"key7": 15
}

keyList = []

def get_keys(inDict, listOfKeys):
    for k, v in inDict.items():
        listOfKeys.append(k)
        if isinstance(v, list):
            for item in v:
                if isinstance(item, dict):
                    get_keys(item, listOfKeys)
        elif isinstance(v, dict):
            get_keys(v, listOfKeys)

get_keys(origDict, keyList)
print(keyList)

打印出来:

['key1', 'key2', 'nestedkey', 'key3', 'key4', 'nestedlevel1key', 
'nestedlevel2key', 'key5', 'key6', 'regularkey', 'key7']```

【讨论】:

    【解决方案3】:

    只是为了好玩,你也可以使用非递归函数来节省时间:

    def get_keys(d):
        out = []
        inside = d
        while inside:
            out.append(list(inside.keys())[0])
            v = inside.pop(out[-1])
            if isinstance(v, dict):
                inside.update(v)
            elif isinstance(v, list) and isinstance(v[0], dict):
                for x in v:
                    inside.update(x)
            else:
                continue
        return out
    
    out = get_keys(d)
    

    输出:

    ['key1', 'key2', 'key3', 'key4', 'key5', 'key6', 'key7', 'nestedkey', 'nestedlevel1key', 'regularkey', 'nestedlevel2key']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-30
      • 2019-06-26
      • 1970-01-01
      • 2014-03-30
      • 2021-05-10
      • 2010-12-08
      • 2021-12-16
      • 2022-06-11
      相关资源
      最近更新 更多