我有一本這樣的字典:
d = {
'hosts': [
{'hostname': 'abc', 'ip': '127.0.0.1', 'extra_check_cmd': 'check-me'},
{'hostname': 'def', 'ip': '127.0.0.2', 'extra_check_cmd': 'check-it,check-this'},
{'hostname': 'ijk,uvw,xyz', 'ip': '127.0.0.3,127.0.0.4,127.0.0.5', 'extra': 'check-me'}
]
}
我想從中創建以下字典
d = {
'hosts': [
{'hostname': 'abc', 'ip': '127.0.0.1', 'extra_check_cmd': 'check-me'},
{'hostname': 'def', 'ip': '127.0.0.2', 'extra_check_cmd': 'check-it'},
{'hostname': 'def', 'ip': '127.0.0.2', 'extra_check_cmd': 'check-this'},
{'hostname': 'ijk', 'ip': '127.0.0.3', 'extra': 'check-me'},
{'hostname': 'uvw', 'ip': '127.0.0.4', 'extra': 'check-me'},
{'hostname': 'xyz', 'ip': '127.0.0.5', 'extra': 'check-me'}
]
}
這意味著在給出值串列的任何地方,每個值串列都應該有一個單獨的子字典。
uj5u.com熱心網友回復:
也許是這樣的?
def expand_dict(host):
# Create all of the possible key-value pairs for each key in the original dictionary
kv_pairs = [[(k, v) for v in vals.split(",")] for k, vals in host.items()]
# Find the number of dictionaries this would expand to
max_len = max(len(p) for p in kv_pairs)
# A list of possible values must either be the length of the number of dictionaries we expect, or length 1 so we can repeat the value max_len times
assert all(len(pairs) in {1, max_len} for pairs in kv_pairs)
# Expand all of the length 1 value lists to length max_len
updated_pairs = [p if len(p) == max_len else p * max_len for p in kv_pairs]
# Return a generator of dictionaries for each of the sets of key-value pairs
return (dict(pairs) for pairs in zip(*updated_pairs))
input_dict = {'hosts': [{'hostname': 'abc', 'ip': '127.0.0.1', 'extra_check_cmd': 'check-me'}, {'hostname': 'def', 'ip': '127.0.0.2', 'extra_check_cmd': 'check-it,check-this'}, {'hostname': 'ijk,uvw,xyz', 'ip': '127.0.0.3,127.0.0.4,127.0.0.5', 'extra': 'check-me'}]}
output_dict = {'hosts': [d for host in input_dict['hosts'] for d in expand_dict(host)]}
進一步分解,讓我們用一個例子來試試。在這種情況下,我使用host = d['hosts'][2].
{'hostname': 'ijk,uvw,xyz',
'ip': '127.0.0.3,127.0.0.4,127.0.0.5',
'extra': 'check-me'}
該行為kv_pairs = [[(k, v) for v in vals.split(",")] for k, vals in host.items()]我們提供了內部專案串列的可能鍵值對串列。
[
[('hostname', 'ijk'), ('hostname', 'uvw'), ('hostname', 'xyz')],
[('ip', '127.0.0.3'), ('ip', '127.0.0.4'), ('ip', '127.0.0.5')],
[('extra', 'check-me')],
]
如您所見,"hostname"和"ip"鍵各有 3 個鍵值對,而"extra"原始主機字典中的鍵只有 1 對。目標是制作 3 個字典,'extra': 'check-me'每個字典中都有。所以,我們想要找到我們期望生成的字典數量。
該行max_len = max(len(p) for p in kv_pairs)給了我們 3。然后,作為一個健全性檢查,我們要確保每組鍵值對的kv_pairs長度為 1 或長度為 3。所以我們添加了 assert assert all(len(pairs) in {1, max_len} for pairs in kv_pairs)。
然后我們通過重復它們將所有長度為 1 kv 的對串列擴展到長度為 3。這個串列理解基本上采用所有長度為 3 的串列,并將長度為 1 的串列每個重復 3 次,因此它們的長度都相同。
updated_pairs = [p if len(p) == max_len else p * max_len for p in kv_pairs]
[[('hostname', 'ijk'), ('hostname', 'uvw'), ('hostname', 'xyz')],
[('ip', '127.0.0.3'), ('ip', '127.0.0.4'), ('ip', '127.0.0.5')],
[('extra', 'check-me'), ('extra', 'check-me'), ('extra', 'check-me')]]
現在一切都很好并且排列整齊,我們可以開始創建字典了。我們可以使用zip()它,它為我們提供了元組的迭代器,其中包含來自我們傳入的每個輸入迭代器的專案。我使用 Python 的解包語法將內部的每個串列展開updated_kv_pairs為zip(). 換句話說,
zip(*updated_kv_pairs)
是相同的
zip(updated_kv_pairs[0], updated_kv_pairs[1], updated_kv_pairs[2])
的每次迭代zip()都會為我們提供包含在我們輸出的單個字典中的鍵值對串列。這給了我們
{'hostname': 'ijk', 'ip': '127.0.0.3', 'extra': 'check-me'}
{'hostname': 'uvw', 'ip': '127.0.0.4', 'extra': 'check-me'}
{'hostname': 'xyz', 'ip': '127.0.0.5', 'extra': 'check-me'}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/387573.html
下一篇:將字串串列添加到字典中的現有鍵
