Функция для динамического извлечения значений из нескольких вложенных словарей в Python

Постановка задачи состоит в том, чтобы написать функцию, которая будет принимать объект входного словаря и возвращать список всех значений, даже в случае многоуровневых вложенных словарей внутри объекта входного словаря.

Пример такого вложенного словаря ниже:

{
    "f_name": "AKASH",
    "s_name": "NASH",
    "professional": {
        "designation": "DE",
        "company": "XYZ",
        "place_of_work": {
            "city": "BLR",
            "state": "KA",
            "country": "IN"
        }
    },
    "personal_address": {
        "city": "EKM",
        "state": "KL",
        "country": "IN"
    }
}

Я написал приведенный ниже код, и я могу извлечь значения словаря, даже в случае одного вложенного словаря, с помощью ручного условного оператора if.

def dic_values(x):
    l =[]
    l1 = []
    if type(x) == dict:
        for i in x:
            if type(x[i]) != dict:
                l.append(x[i])
            elif type(x[i])== dict:
                y = x[i]
                for j in y:
                    l1.append(y[j])
    else:
        "Please input a dict object"
    l.extend(l1)
    return l

СЛУЧАЙ 1:
При запуске функции с объектом dict с одним вложенным словарем внутри:

dic_values({"name":"AKASH","s_name":"NASH", "place":{"city":"BLR","state":"KA","country":"IN"}})

Ожидаемый результат:

['AKASH', 'NASH', 'BLR', 'KA', 'IN']

СЛУЧАЙ 2:
Как и в приведенном ниже примере, при наличии ввода многоуровневых вложенных словарей внутри:

dic_values({"f_name":"AKASH","s_name":"NASH","professional":{"designation":"DE","company":"XYZ","place_of_work":{"city":"BLR","state":"KA","country":"IN"}}, "personal_address":{"city":"EKM","state":"KL","country":"IN"}})

Выход:

['AKASH','NASH','DE','XYZ', {'city': 'BLR', 'state': 'KA', 'country': 'IN'}, 'EKM', 'KL', 'IN']

Ожидаемый результат:

['AKASH','NASH','DE','XYZ', 'BLR', 'KA', 'IN', 'EKM', 'KL', 'IN']

ВОПРОС:
Скажем, внутри объекта входного словаря присутствовали вложенные словари. Я хотел бы написать код, в котором код динамически проверяет наличие многоуровневого вложенного словаря и выполняется. Как и в случае СЛУЧАЯ 2. Ожидаемый результат.

Поскольку это похоже на домашнее задание, я не буду давать ответ, а предложу путь решения: обратите внимание, что вы можете сделать свою функцию рекурсивной. Вы перебираете каждое значение в словаре, добавляя их в выходной список, если не найдете словарь. В этом случае вы расширяете список результата вызова dic_values в словаре (это ваш рекурсивный вызов). Это должно обрабатывать любое разумное количество уровней словаря.

nonDucor 05.04.2023 23:58

На самом деле не сложнее использовать стек для этого. Поместите исходный дикт в список. Пока этот список содержит что-то, вытащите следующий диктофон. Прокручивайте значения, добавляйте значения, которые являются диктовками, обратно в стек, помещайте значения, которых нет во втором списке возвращаемых значений. Когда стек пуст, верните второй список.

Mark 06.04.2023 00:13

@Mark Поскольку это python (и у нас переполнение стека), я думаю, что это решение является лучшим выбором, поскольку управление памятью для рекурсии не является сильной стороной python.

lotus 06.04.2023 00:17

@nonDucor Цените решение. Спасибо

Saheen AHZAN 06.04.2023 00:46
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
92
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий
def all_dict_values(input_dict):
    result = []
    for value in input_dict.values():
        if isinstance(value, dict):
            result.extend(all_dict_values(value))
        else:
            result.append(value)
    return result

Спасибо за ответ. Очень помог в решении моей проблемы и в понимании новой функции isintamce()

Saheen AHZAN 06.04.2023 00:40

измените существующий код для рекурсивного вызова dic_values:

def dic_values(x):
    if not isinstance(x, dict):
        return [x]
    res = []
    for v in x.values():
        res.extend(dic_values(v))
    return [v for v in res if not isinstance(v, dict)]

Спасибо за ответ. Это сработало. Хотя другой ответ был более понятен для n00b вроде меня. Цените свое время.

Saheen AHZAN 06.04.2023 00:41

добро пожаловать, если вы проголосуете

Phoenix 06.04.2023 00:49

Если бы. Я новичок в StackOverflow, и у меня пока нет репутации. Как только получу, обязательно так и сделаю.

Saheen AHZAN 06.04.2023 01:00

Если вы заинтересованы в том, чтобы сделать это нерекурсивным способом. Вы можете поддерживать стек диктов по ходу дела. Пока в стеке есть словари, нужно найти больше значений:

def dic_values(d):
    assert isinstance(d, dict), "Please pass a dict"
    
    values = [] # this will hold the values
    stack = [d] # this should only contain dicts 
    
    while stack:
        next_d = stack.pop()
        for v in next_d.values():
            if isinstance(v, dict):
                stack.append(v) # put it back to process more
            else:
                values.append(v) # this a not dict, add it to the return list
    return values
        
        
dic_values({"f_name":"AKASH","s_name":"NASH","professional":{"designation":"DE","company":"XYZ","place_of_work":{"city":"BLR","state":"KA","country":"IN"}}, "personal_address":{"city":"EKM","state":"KL","country":"IN"}})
# ['AKASH', 'NASH', 'EKM', 'KL', 'IN', 'DE', 'XYZ', 'BLR', 'KA', 'IN']

Большая помощь. Замечательно объяснил. Спасибо Марк :)

Saheen AHZAN 06.04.2023 02:30

Другие вопросы по теме