Есть ли эффективный способ накапливать значения из вложенного экземпляра в Python? - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть экземпляр, который выглядит следующим образом:

{
    "_id": "cgx", 
    "capacity": 1000000000, 
    "chunks": [
        {
            "prs": [
                {
                    "segs": [
                        {
                            "node_id": "server-0",
                        }
                    ]
                }
            ]
        },
        {
            "prs": [
                {
                    "segs": [
                        {
                            "node_id": "server-2",
                        }
                    ]
                },
               {
                    "segs": [
                        {
                            "node_id": "server-3",
                        }
                    ]
                }
            ]
        }
    ], 
    "health": "healthy", 
    "status": "ok"
}

каждый «чанк» в массиве чанков является экземпляром Chunk, каждый «pr» в массиве prs является экземпляром Pr, каждый «seg»'в массиве segs находится экземпляр Seg

Я хочу пройти через экземпляр и накапливать набор значений' node_id 'из всех экземпляров.Я сделал это следующим образом:

 def setDistinctElements(self, result):
            elements = []
            for chunk in getattr(result, 'chunks'):
                for pr in getattr(chunk, 'prs'):
                    for seg in getattr(pRaid, 'segs'):
                        elements.append(getattr(seg, 'node_id'))

Есть ли более эффективный способ сделать это вместо цикла 3 раза?В каждом таком экземпляре может быть много вложенных экземпляров «chunks», «prs» и «segs».

Ответы [ 2 ]

1 голос
/ 24 апреля 2019

Я не смог запустить твой код, поэтому сделал похожий. и чтобы запустить его быстрее, я конвертирую json в string и связываюсь с ним, чтобы получить то, что мне нужно. и это почти X2 быстрее 1

lst = []
for row in a.replace('[','').replace(' ','').replace('{','').replace('\n','').replace(']','').replace('}','').replace('"','').sp
lit(','):
if "node_id" in row:
      lst.append(row.split(':')[-1])
0 голосов
/ 24 апреля 2019

Вы можете использовать рекурсию с генератором, чтобы пройти структуру любой глубины:

data = {'_id': 'cgx', 'capacity': 1000000000, 'chunks': [{'prs': [{'segs': [{'node_id': 'server-0'}]}]}, {'prs': [{'segs': [{'node_id': 'server-2'}]}, {'segs': [{'node_id': 'server-3'}]}]}], 'health': 'healthy', 'status': 'ok'}

def get_nodes(d):
  for a, b in d.items():
    if a == 'node_id':
      yield b
    elif isinstance(b, dict):
      yield from get_nodes(b)
    elif isinstance(b, list):
      for c in b:
        yield from get_nodes(c)

print(list(get_nodes(data)))

Выход:

['server-0', 'server-2', 'server-3']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...