Получить список всех подразделов из словаря Python - PullRequest
3 голосов
/ 19 марта 2019

У меня есть несколько словарей (вывод json).Я хочу получить базовый элемент, который может быть списком строк или строк.В настоящее время я делаю это так: -

folder="shared/"
files=os.listdir('shared')


for f in files:
    f=folder+f
    print(f)
    with open(f) as f:
        data = json.load(f)
    #data is a dict now with sub-keys
    for key,value in data.items():
        if value.keys():
            print(value)
    break

Это словарь ввода, который был прочитан кодом Python: -

{
  "shortshirt": {
    "ralphlauren": {
      "classic": [
        "That Ralph Lauren classic fit is a timeless look!",
        "Nice choice. Can’t go wrong with Ralph Lauren"
      ]
    }
  },
  "socks": {
    "": {
      "": ["Have to find the right socks to keep your feet cozy"]
    }
  }
}

И это вывод, который я получаю: -

{'ralphlauren': {'classic': ['That Ralph Lauren classic fit is a timeless look!', 'Nice choice. Can’t go wrong with Ralph Lauren']}}
{'': {'': ['Have to find the right socks to keep your feet cozy']}}

Но это то, что я хочу: -

keys=[["shortshirt","ralphlauren","classic"],["socks"]]

value=[['That Ralph Lauren classic fit is a timeless look!', 'Nice choice. Can’t go wrong with Ralph Lauren'], ['Have to find the right socks to keep your feet cozy']]

Но я не знаю, иметь ли 2 или 3 уровня вложенных циклов.Если у меня есть внутренний цикл и в действительности не было вложенного ключа, я получаю ошибку значения.Я хочу получить все вложенные ключи в отдельном списке и базовое значение или значения, как на самом низком уровне в другом списке, любая помощь в этом отношении будет высоко оценена.

1 Ответ

1 голос
/ 19 марта 2019

Генераторы полезны для этой проблемы.Стратегии -

  • Ключи: отслеживать текущий путь рекурсии.Получите текущий путь, как только вы нажмете на лист.

  • Значения: только листья урожая.

Код:

def getitems(obj):

  def getkeys(obj, stack):
    for k, v in obj.items():
      k2 = ([k] if k else []) + stack # don't return empty keys
      if v and isinstance(v, dict):
        for c in getkeys(v, k2):
          yield c
      else: # leaf
        yield k2

  def getvalues(obj):
    for v in obj.values():
      if not v: continue
      if isinstance(v, dict):
        for c in getvalues(v):
          yield c
      else: # leaf
        yield v if isinstance(v, list) else [v]

  return list(getkeys(obj,[])), list(getvalues(obj))

Вход:

{
  "shortshirt": {
    "ralphlauren": {
      "classic": [
        "That Ralph Lauren classic fit is a timeless look!",
        "Nice choice. Can't go wrong with Ralph Lauren"
      ]
    }
  },
  "socks": {
    "": {
      "": ["Have to find the right socks to keep your feet cozy"]
    }
  }
}

Выход:

# keys
[['classic', 'ralphlauren', 'shortshirt'], ['socks']]

# values
[['That Ralph Lauren classic fit is a timeless look!', "Nice choice. Can't go wrong with Ralph Lauren"], ['Have to find the right socks to keep your feet cozy']]
...