python распаковывает вложенный словарь и хранит ключи и значения в кортежах - PullRequest
0 голосов
/ 15 сентября 2018

Если у меня есть что-то вроде этого:

dic = {"hi": 5, "test": {"apple": 2, "orange": 3}, "sa": "ok"}

, и я хочу, чтобы мой вывод был таким:

[("hi", 5), ("apple", 2), ("orange": 3), ("sa", "ok")]

с каждым ключом и значением рядом друг с другом.Я проигнорировал ключ «test» в конечном выводе, потому что его значение является словарем.

Ответы [ 5 ]

0 голосов
/ 15 сентября 2018

Я думаю, что лучший подход к решению этой проблемы - это рекурсия, на случай, если вы столкнетесь с чем-то очень странным. Например, словарь в словаре в словаре (dictionaryception) /s.

def flattenDict(aDict):
    result = []
    for i in aDict: #we iterate through the dictionary
        if isinstance(aDict[i], dict): #if the value of the key is a dictionary
            result.extend(flattenDict(aDict[i])) #recursion
        else:
            result.append((i, aDict[i])) #else we append the value in the result list.
    return result

Выход:

[('hi', 5), ('apple', 2), ('orange', 3), ('sa', 'ok')]
0 голосов
/ 15 сентября 2018

Рекурсивное решение:

from itertools import chain
def flatten(d):
    return chain.from_iterable([(k,v)] if not isinstance(v,dict) else flatten(v) 
                               for k,v in d.items())
list(flatten(dic))
#[('hi', 5), ('apple', 2), ('orange', 3), ('sa', 'ok')]
0 голосов
/ 15 сентября 2018

Возможное решение, которое решает только два уровня вложенности (как указано выше):

  def loop_dict(d: dict):
      """continue to pop until no more dict d"""
      while d:
          yield d.popitem()

 output = []
 for k, v in loop_dict(dic):
     if type(v) == dict:
         output.extend(loop_dict(v))
     else:
         output.append((k, v))

Чтобы пойти дальше, вы можете реализовать некоторые рекурсивные вызовы.Который в основном будет углубляться, чтобы найти самое глубокое гнездо и распространяться назад.

0 голосов
/ 15 сентября 2018

Если ("orange": 3) в ожидаемом результате в исходном вопросе является опечаткой, а желаемый результат - список кортежей, самый простой ответ может быть:

dic = {"hi": 5, "test": {"apple": 2, "orange": 3}, "sa": "ok"}

l = []

for key in dic.keys():
    if isinstance(dic[key], dict):
        l.extend(dic[key].items())
        continue

    l.append((key, dic[key]))

print l

результаты:

[('orange', 3), ('apple', 2), ('sa', 'ok'), ('hi', 5)]
0 голосов
/ 15 сентября 2018

Вот предложение о том, как вы можете справиться с этим, предполагая («оранжевый»: 3) в выводе вместо («оранжевый», 3):

def work(di):
    def f(di):
        for i in di:
            if isinstance(di[i],dict):
                yield f(di[i])
            else:
                yield (i,di[i])               
    result = [] 
    for item in f(di):
        result+=[item] if isinstance(item,tuple) else list(item)
    return result

dic = {"hi": 5, "test": {"apple": 2, "orange": 3}, "sa": "ok"}
print(work(dic))

#Output
[('hi', 5), ('apple', 2), ('orange', 3), ('sa', 'ok')]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...