[英]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.