Рекурсивно сплющить объект - PullRequest
0 голосов
/ 31 декабря 2018

У меня есть следующий объект:

d={
   'CollectionTitleIDs': {
           '852070#TVEpisode': '12', 
           '852063#TVEpisode': '4', 
           '852067#TVEpisode': '9'
     }, 
    'ReleaseYear': '2005', 
    'TVSeriesID': '5638#TVSeries'
}

Я бы хотел сгладить его, чтобы получить следующий вывод:

{
   'CollectionTitleIDs': [
      {"_Key": "852070#TVEpisode", "Value": "12"},
      {"_Key": "852063#TVEpisode", "Value": "4"},
      {"_Key": "852067#TVEpisode", "Value": "9"}
    ]
    'ReleaseYear': '2005', 
    'TVSeriesID': '5638#TVSeries'
}

Другими словами, если значение ключа равноdict, чтобы вставить ключи этого dict в поле «_Key» и значение этого в поле «Value».

У меня были трудности с рекурсией.И в настоящее время у меня есть что-то вроде этого:

То, что у меня сейчас есть:

def flatten_obj(obj, FLAT_OBJ=None):

    if FLAT_OBJ is None: FLAT_OBJ = OrderedDict()
    if isinstance(obj, list):
        return [flatten_obj(l, FLAT_OBJ=FLAT_OBJ) for l in obj]
    elif not isinstance(obj, dict):
        return obj
    else:
        for key in list(obj.keys()):
            val = get_sub_object_from_path(obj, key)
            if isinstance(val, dict):
                FLAT_OBJ[key] = [{'_Key': subkey, 'Value': flatten_obj(subval)} for subkey, subval in val.items()]
            elif isinstance(val, list):
                FLAT_OBJ[key] = flatten_obj(val, FLAT_OBJ=FLAT_OBJ)
            else:
                FLAT_OBJ[key] = val
    return FLAT_OBJ

Обратите внимание, что у приведенного выше есть один уровень рекурсии, но возможно, что «значение» будет иметь (кроме того) вложенный объект, и в этом случае мы хотим снова извлечь _Key, значение.

Ответы [ 3 ]

0 голосов
/ 31 декабря 2018

Мой метод:

d={
   'CollectionTitleIDs': {
           '852070#TVEpisode': '12', 
           '852063#TVEpisode': '4', 
           '852067#TVEpisode': '9'
     }, 
    'ReleaseYear': '2005', 
    'TVSeriesID': '5638#TVSeries'
}

d['CollectionTitleIDs'] = list(map(lambda x: {'_Key': x[0], 'Value': x[1]}, d['CollectionTitleIDs'].items()))

#{
#  'CollectionTitleIDs': [
#    {'_Key': '852070#TVEpisode', 'Value': '12'},
#    {'_Key': '852063#TVEpisode', 'Value': '4'}, 
#    {'_Key': '852067#TVEpisode', 'Value': '9'}
#  ], 
#  'ReleaseYear': '2005', 
#  'TVSeriesID': '5638#TVSeries'
#}
0 голосов
/ 31 декабря 2018

Код должен быть проще, чем:

  1. Если это список, вернуть список сплющенных объектов
  2. Если это dict, вернуть список объектов key / val
  3. в противном случае просто верните x

в коде:

def flatten1(x):
    if isinstance(x, list):
        return [flatten1(y) for y in x]
    elif isinstance(x, dict):
        return [{"_Key": key, "Value": flatten1(value)}
                for key, value in x.items()]
    else:
        return x

В вашем примере, однако, по какой-то причине toplevel не выравнивается ивместо этого - обычный dict, тогда просто сделайте так, чтобы

def flatten(x):
    if isinstance(x, dict):
       return {key: flatten1(value) for key, value in x.items()}
    else:
       return flatten1(x)

flatten1 даже можно было сделать внутренней функцией:

def flatten(x):
    def flatten1(x):
        if isinstance(x, list):
            return [flatten1(y) for y in x]
        elif isinstance(x, dict):
            return [{"_Key": key, "Value": flatten1(value)}
                    for key, value in x.items()]
        else:
            return x

    if isinstance(x, dict):
       return {key: flatten1(value) for key, value in x.items()}
    else:
       return flatten1(x)
0 голосов
/ 31 декабря 2018

Вы можете использовать распаковку со списком:

d = {'CollectionTitleIDs': {'852070#TVEpisode': '12', '852063#TVEpisode': '4', '852067#TVEpisode': '9'}, 'ReleaseYear': '2005', 'TVSeriesID': '5638#TVSeries'}
new_d = {**d, 'CollectionTitleIDs':[{'_Key':a, 'Value':b} for a, b in d['CollectionTitleIDs'].items()]}

Вывод:

{'CollectionTitleIDs': 
  [{'_Key': '852070#TVEpisode', 'Value': '12'}, 
   {'_Key': '852063#TVEpisode', 'Value': '4'}, 
   {'_Key': '852067#TVEpisode', 'Value': '9'}], 
 'ReleaseYear': '2005', 'TVSeriesID': '5638#TVSeries'}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...