简体   繁体   中英

How to extract values from each entry in nested dictionary?

I have a program that parses a maven dependency tree & organizes the data how I want. I'm unsure of how to index into the data properly in order to return the it. Here is an excerpt of what the outputted data from the maven dependency tree parser looks like (using pprint).

[{'name': 'org.antlr'},
 {'type': 'dependency'},
 {'metadata': [{'groupId': 'org.antlr'},
               {'artifactId': 'antlr4',
                'children': [({'name': 'org.antlr'},
                              {'type': 'dependency'},
                              {'metadata': [{'groupId': 'org.antlr'},
                                            {'artifactId': 'antlr4-runtime'}]}),
                             ({'name': 'org.antlr'},
                              {'type': 'dependency'},
                              {'metadata': [{'groupId': 'org.antlr'},
                                            {'artifactId': 'antlr-runtime'}]}),
                             ({'name': 'org.antlr'},
                              {'type': 'dependency'},
                              {'metadata': [{'groupId': 'org.antlr'},
                                            {'artifactId': 'ST4'}]}),
                             ({'name': 'org.abego.treelayout'},
                              {'type': 'dependency'},
                              {'metadata': [{'groupId': 'org.abego.treelayout'},
                                            {'artifactId': 'org.abego.treelayout.core'}]}),
                             ({'name': 'org.glassfish'},
                              {'type': 'dependency'},
                              {'metadata': [{'groupId': 'org.glassfish'},
                                            {'artifactId': 'javax.json'}]}),
                             ({'name': 'com.ibm.icu'},
                              {'type': 'dependency'},
                              {'metadata': [{'groupId': 'com.ibm.icu'},
                                            {'artifactId': 'icu4j'}]})]}]}]

I have tried:

pprint([name for name in parsedTree[0]])

or

pprint(parsedTree[0:1])

or variations of these where parsedTree is the output shown above.

Ultimately I want to return only the names of each perhaps using recursion or a generator to prepare this info for an API call. I do not know how to index & extract name alone (without the metadata or type). Is there a way to do this? Thank you in advance. I want to get each name separately so that if I do something like Beans.name it returns

org.antlr
org.antlr
org.antlr
org.antlr
org.antlr
org.abego.treelayout
org.glassfish
com.ibm.icu

My previous answer was wrong, I think this should work:

def get_all_names(parsed_tree, li):
    if not isinstance(parsed_tree, list) and not isinstance(parsed_tree, tuple):
        return li
    def get_all_names_dict(dictionary, li):
        if not isinstance(dictionary, dict):
            get_all_names(dictionary, li)
            return
        for key in dictionary.keys():
            if key == 'name':
                li.append(dictionary[key])
            elif isinstance(dictionary[key], dict):
                get_all_names_dict(dictionary[key], li)
            elif isinstance(dictionary[key], list):
                get_all_names(dictionary[key], li)
            elif isinstance(dictionary[key], tuple):
                get_all_names(dictionary[key], tuple)
    for val in parsed_tree:
        get_all_names_dict(val, li)
    return li

print('\n'.join(get_all_names(parsedTree, [])))

Sorry for the wait!

You need to dive only on dicts, tuples and dictionaries to search dictionaries with the key "name". If you are expecting other types here, include them on the relevant "isinstance" checks.


def get_nested_name(tree):
    names = []
    if isinstance(tree, (list, tuple)):
        for branch in tree:
            names.extend(get_nested_name(branch))

    elif isinstance(tree, dict):
        try:
            names.append(tree['name'])
        except KeyError:
            # this dict dont have a "name" key, lets ignore it
            pass

        branches = filter(lambda x: isinstance(x, (list, dict, tuple)), tree.values())
        for b in branches:
            names.extend(get_nested_name(b))

    return names

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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