[英]How do I turn a nested dict of lists (with dicts) into a single list of dicts?
我想將一個非常復雜的字典轉換為一個帶有字典的列表(如 SQL 連接)。
輸入:
{
'company': 'A',
'employee': [
{'name': 'John', 'skills': ['python', 'java']},
{'name': 'Mary', 'skills': ['web', 'databases']}
]
}
Output:
[
{'company': 'A', 'employee': {'name': 'John', 'skills': 'python'}},
{'company': 'A', 'employee': {'name': 'John', 'skills': 'java'}},
{'company': 'A', 'employee': {'name': 'Mary', 'skills': 'web'}},
{'company': 'A', 'employee': {'name': 'Mary', 'skills': 'databases'}},
]
我希望能夠添加更多嵌套列表以及添加更多公司等......所以硬編碼字典和列表的級別不是一種選擇。 遞歸似乎是我唯一的選擇。
有沒有人有任何指示如何 go 這樣做?
對於第一級,我想出了這個,但是當我開始遞歸調用 flatten function 時遇到了麻煩
def flatten(input):
output = []
for item in input:
if isinstance(input[item], list):
for subitem in input[item]:
copy = input
# Doesnt work
# copy[item] = flatten(subitem)
# Only works for the first layer
copy[item] = subitem
output.append(copy.copy())
return output
print(flatten(start))
此代碼適用於第一級(為每個員工添加新記錄),但遞歸調用 flatten 會使 output 返回一個空列表
假設輸入 dict 中始終只有一個值是一個列表,您可以先找到具有列表值的鍵,然后返回當前 dict 的列表,並將該鍵的值替換為遞歸展平的每個值,直到該值不再是一個字典:
def flatten(d):
if isinstance(d, dict):
key, lst = next((k, v) for k, v in d.items() if isinstance(v, list))
return [{**d, **{key: v}} for record in lst for v in flatten(record)]
else:
return [d]
flatten(d)
返回(給定樣本輸入 dict 為d
):
[{'company': 'A', 'employee': {'name': 'John', 'skills': 'python'}},
{'company': 'A', 'employee': {'name': 'John', 'skills': 'java'}},
{'company': 'A', 'employee': {'name': 'Mary', 'skills': 'web'}},
{'company': 'A', 'employee': {'name': 'Mary', 'skills': 'databases'}}]
或者,如果 dict 中可能存在一個沒有列表值的級別,在這種情況下,使用上面的代碼調用next
function 將產生一個StopIteration
,您可以捕獲該異常並返回輸入 dict就像在列表中一樣,並且由於當輸入不是字典時這是相同的行為,您可以簡單地捕獲AttributeError
異常(當給定的 object 沒有items
屬性時產生)也可以使用相同的處理程序代碼處理這兩種情況:
def flatten(d):
try:
key, lst = next((k, v) for k, v in d.items() if isinstance(v, list))
except (StopIteration, AttributeError):
return [d]
return [{**d, **{key: v}} for record in lst for v in flatten(record)]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.