簡體   English   中英

遍歷列表並將數據添加到 Python 中的另一個嵌套字典列表中

[英]Iterate over a list and add the data into another nested list of dictionary in Python

我這里有個問題:

orgn_data = [{ "host1" : [{'port': 8080, 'name': 'data1'}, {'port': 8000, 'name': 'data2'}, {'port': 80, 'name': 'data3'}]},
             {"host2": [{'port': 443, 'name': 'data1'}, {'port': 8000, 'name': 'data2'}]}
            ]

res_data = [{'host1': ['1', '0', '1']}, {'host2': ['1', '0']}] 

基本上, res_data 是與 orgn_data 列表具有相同主機的結果列表。 我想將同一主機的 res_data 以相同的順序合並到 orgn 列表中。
我可以保證 res_data 的順序與 orgn_data 本身相同。 但是,外部列表可能並不總是與它總是相同的順序(可能是多個主機)。 這意味着,必須首先查找主機名才能獲得正確的配對。

最終結果應如下所示:

final_data = [{ "host1" : [{'port': 8080, 'name': 'data1', "status": 1}, {'port': 8000, 'name': 'data2', "status": 0}, {'port': 80, 'name': 'data3', "status": 1}]},
              {"host2": [{'port': 443, 'name': 'data1', "status": 1}, {'port': 8000, 'name': 'data2', "status": 0}]}
             ]

做這個的最好方式是什么? 非常感謝這個!

import copy
final_data = copy.deepcopy(orgn_data)
aux_dict = { host:lst for d in res_data for host, lst in d.items() }
# aux_dict == {'host1': ['1', '0', '1'], 'host2': ['1', '0']}
for dct in final_data:
    # dct == { "host1" : [{'port': 8080, 'name': 'data1'}, {'port': 8000, 'name': 'data2'}, {'port': 80, 'name': 'data3'}]} etc.
    for host, lst in dct.items():
    # host == "host1" --> lst == [{'port': 8080, 'name': 'data1'}, {'port': 8000, 'name': 'data2'}, {'port': 80, 'name': 'data3'}]
        for i, subdct in enumerate(lst):
            # i == 0 --> subdct == {'port': 8080, 'name': 'data1'}
            subdct['status'] = aux_dict[host][i]

已經有一些很好的答案,我使用itertools.groupby添加了一個:

from itertools import groupby

for k, (orgn, res) in groupby(sorted(orgn_data + res_data, key=lambda k: [*k.keys()][0]), lambda k: [*k.keys()][0]):
    for v, s in zip(orgn[k], res[k]):
        v['status'] = s

print(orgn_data)

印刷:

[{'host1': [{'port': 8080, 'name': 'data1', 'status': '1'}, {'port': 8000, 'name': 'data2', 'status': '0'}, {'port': 80, 'name': 'data3', 'status': '1'}]}, 
 {'host2': [{'port': 443, 'name': 'data1', 'status': '1'}, {'port': 8000, 'name': 'data2', 'status': '0'}]}]

如果您的目標是更新orgn_data以包含status鍵:

order = lambda x: next(iter(x.keys()))
for org, res in zip(*map(lambda lst: sorted(lst, key=order), (orgn_data, res_data))):
  for key, lst in org.items():
    for i, inner in enumerate(lst):
      inner['status'] = res[key][i]

結果:

[{'host1': [{'name': 'data1', 'port': 8080, 'status': '1'},
            {'name': 'data2', 'port': 8000, 'status': '0'},
            {'name': 'data3', 'port': 80, 'status': '1'}]},
 {'host2': [{'name': 'data1', 'port': 443, 'status': '1'},
            {'name': 'data2', 'port': 8000, 'status': '0'}]}]

如果您想要數據的副本,另一個答案可以更好地覆蓋您。 但如果你喜歡冒險和瘋狂,你可以試試這個:

order = lambda x: next(iter(x.keys()))

final_data = [
  {key: [
    {k: v for k, v in list(inner.items()) + [('status', res[key][i])]}
    for i, inner in enumerate(lst)
    ]
  }
  for org, res in zip(*map(lambda lst: sorted(lst, key=order), (orgn_data, res_data)))
  for key, lst in org.items()
]

示例代碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM