简体   繁体   English

"获取嵌套字典中所有键的列表"

[英]Get a list of all keys in nested dictionary

I want to get a list of all keys in a nested dictionary that contains lists and dictionaries.我想获取包含列表和字典的嵌套字典中所有键的列表。

I currently have this code, but it seems to be missing adding some keys to the list and also duplicate adds some keys.我目前有这段代码,但似乎缺少向列表中添加一些键,并且重复添加了一些键。

keys_list = []
def get_keys(d_or_l, keys_list):
    if isinstance(d_or_l, dict):
        for k, v in iter(sorted(d_or_l.iteritems())):
            if isinstance(v, list):
                get_keys(v, keys_list)
            elif isinstance(v, dict):
                get_keys(v, keys_list)
            else:
                keys_list.append(k)
    elif isinstance(d_or_l, list):
        for i in d_or_l:
            if isinstance(i, list):
                get_keys(i, keys_list)
            elif isinstance(i, dict):
                get_keys(i, keys_list)
    else:
        print "** Skipping item of type: {}".format(type(d_or_l))
    return keys_list

This should do the job:这应该可以完成这项工作:

def get_keys(dl, keys_list):
    if isinstance(dl, dict):
        keys_list += dl.keys()
        map(lambda x: get_keys(x, keys_list), dl.values())
    elif isinstance(dl, list):
        map(lambda x: get_keys(x, keys_list), dl)

To avoid duplicates you can use set, eg:为避免重复,您可以使用 set,例如:

keys_list = list( set( keys_list ) )

Example test case:示例测试用例:

keys_list = []
d = {1: 2, 3: 4, 5: [{7: {9: 1}}]}
get_keys(d, keys_list)
print keys_list
>>>> [1, 3, 5, 7, 9]

As it stands, your code ignores keys that lead to list or dict values.就目前而言,您的代码会忽略导致listdict值的键。 Remove the else block in your first for loop, you want to add the key no matter what the value is.删除第一个for循环中的else块,无论值是什么,您都希望添加键。

keys_list = []
def get_keys(d_or_l, keys_list):
    if isinstance(d_or_l, dict):
        for k, v in iter(sorted(d_or_l.iteritems())):
            if isinstance(v, list):
                get_keys(v, keys_list)
            elif isinstance(v, dict):
                get_keys(v, keys_list)
            keys_list.append(k)   #  Altered line
    elif isinstance(d_or_l, list):
        for i in d_or_l:
            if isinstance(i, list):
                get_keys(i, keys_list)
            elif isinstance(i, dict):
                get_keys(i, keys_list)
    else:
        print "** Skipping item of type: {}".format(type(d_or_l))
    return keys_list

get_keys({1: 2, 3: 4, 5: [{7: {9: 1}}]}, keys_list) returns [1, 3, 9, 7, 5] get_keys({1: 2, 3: 4, 5: [{7: {9: 1}}]}, keys_list)返回[1, 3, 9, 7, 5]

To avoid duplication, you could use a set datatype instead of a list .为避免重复,您可以使用set数据类型而不是list

Updating @MackM's response to Python 3 as dict.iteritems has been deprecated (and I prefer to use f-strings over the .format{} styling):更新@MackM 对 Python 3 的响应,因为dict.iteritems已被弃用(我更喜欢在.format{}样式上使用 f 字符串):

keys_list = []
def get_keys(d_or_l, keys_list):
    if isinstance(d_or_l, dict):
        for k, v in iter(sorted(d_or_l.items())):  #  Altered line to update deprecated method
            if isinstance(v, list):
                get_keys(v, keys_list)
            elif isinstance(v, dict):
                get_keys(v, keys_list)
            keys_list.append(k)   
    elif isinstance(d_or_l, list):
        for i in d_or_l:
            if isinstance(i, list):
                get_keys(i, keys_list)
            elif isinstance(i, dict):
                get_keys(i, keys_list)
    else:
        print(f'** Skipping item of type: {type(d_or_l)}')  #  Altered line to use f-strings
    return keys_list


unique_keys = list(set(get_keys(my_json_dict, keys_list)))  # Added line as example use case

Here is a simple solution:这是一个简单的解决方案:

def get_nested_keys(d, keys):
    for k, v in d.items():
        if isinstance(v, dict):
            get_nested_keys(v, keys)
        else:
            keys.append(k)

keys_list = []
get_nested_keys(test_listing, keys_list)
print(keys_list)

If you want to know the hierarchy of the keys as well, you can modify the function like so:如果您还想知道键的层次结构,可以像这样修改函数:

def get_nested_keys(d, keys, prefix):
    for k, v in d.items():
        if isinstance(v, dict):
            get_nested_keys(v, keys, f'{prefix}:{k}')
        else:
            keys.append(f'{prefix}:{k}')

I would extend @pm007 answer by a python 2 & 3 friendly version:我将通过 python 2 & 3 友好版本扩展@pm007 答案:

def get_keys(dl, keys=None):
    keys = keys or []
    if isinstance(dl, dict):
        keys += dl.keys()
        list(map(lambda x: get_keys(x, keys), dl.values()))
    elif isinstance(dl, list):
        list(map(lambda x: get_keys(x, keys), dl))
    return list(set(keys))
d = {1: 2, 3: 4, 5: {7: {1: 1}}}
get_keys(d)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM