[英]dict from a dict of list
我有一个 Python 字典,格式如下:
d1 = {'Name':['ABC'], 'Number':['123'], 'Element 1':['1', '2', '3'],
'Element2':['1','2','3']}
预期 output:
{'Name': 'ABC', 'Number': '123',
'Elements': [{'Element 1': '1', 'Element2': '1'},
{'Element 1': '2', 'Element2': '2'},
{'Element 1': '3', 'Element2': '3'}]
我尝试了以下方法:
[{k: v[i] for k, v in d1.items() if i < len(v)}
for i in range(max([len(l) for l in d1.values()]))]
但得到这个结果:
[{'Name': 'ABC', 'Number': '123', 'Element 1': '1', 'Element 2': '1'},
{'Element 1': '2', 'Element 2': '2'},
{'Element 1': '3', 'Element 2': '3'}]
我怎么能从这里 go ?
我强烈建议不要尝试在一行中做所有事情。 如果您有任何分支逻辑或嵌套循环,它并不总是更有效,而且几乎总是不太可读。
给定您的字典,我们可以将Name
和Number
键pop()
到我们的新字典中。 然后
output = dict()
d1 = {'Name':['ABC'], 'Number':['123'], 'Element 1':['1', '2', '3'], 'Element2':['1','2','3']}
output["Name"] = d1.pop("Name")
output["Number"] = d1.pop("Number")
print(output)
# prints:
# {'Name': ['ABC'], 'Number': ['123']}
print(d1)
# prints:
# {'Element 1': ['1', '2', '3'], 'Element2': ['1', '2', '3']}
然后,我们 zip 字典中所有剩余的值,并将它们添加到一个新列表中:
mylist = []
keys = d1.keys()
for vals in zip(*d1.values()):
temp_obj = dict(zip(keys, vals))
mylist.append(temp_obj)
print(mylist)
# prints:
# [{'Element 1': '1', 'Element2': '1'},
# {'Element 1': '2', 'Element2': '2'},
# {'Element 1': '3', 'Element2': '3'}]
最后,将其分配给output["Elements"]
output["Elements"] = mylist
print(output)
# prints:
# {'Name': ['ABC'], 'Number': ['123'], 'Elements': [{'Element 1': '1', 'Element2': '1'}, {'Element 1': '2', 'Element2': '2'}, {'Element 1': '3', 'Element2': '3'}]}
由于您不想硬编码前两个键,
for k, v in d1.items():
if "element" not in k.lower():
output[k] = v
或作为字典理解:
output = {k: v for k, v in d1.items() if "element" not in k.lower()}
使用元组列表来创建字典的元素列表。 使用 Convert 从元组构建您的字典项。
#https://www.geeksforgeeks.org/python-convert-list-tuples-dictionary/
d1 = {'Name':['ABC'], 'Number':['123'], 'Element 1':['1', '2', '3'],
'Element2':['1','2','3']}
def Convert(tup, di):
for a, b in tup:
di[a]=b
return di
dict={}
listElements=[]
for key,value in d1.items():
if isinstance(value,list) and len(value)>1:
for item in value:
listElements.append((key,item))
elif isinstance(value,list) and len(value)==1:
dict[key]=value[0]
else:
dict[key]=value
dict['Elements']=[Convert([(x,y)],{}) for x,y in listElements]
print(dict)
output:
{'Name': 'ABC', 'Number': '123', 'Elements': [{'Element 1': '1'}, {'Element 1': '2'}, {'Element 1': '3'}, {'Element2': '1'}, {'Element2': '2'}, {'Element2': '3'}]}
我将逐步解释:
我们构建new_d1
变量,即您期望的字典 output 并且它被初始化为{'Name': 'ABC', 'Number': '123'}
。 为了实现上述目的,我们使用理解符号,同时考虑到键!=
'Element'
new_d1 = {key: d1.get(key)[0] for key in filter(lambda x: 'Element' not in x, d1)}
我们构建elements
变量,这是一个包含字典的列表,对我们来说很重要,我的意思是,我们必须操纵字典才能达到预期的结果。 然后elements
是[{'Element 1': ['1', '2', '3']}, {'Element2': ['1', '2', '3']}]
。
elements = [{key: d1.get(key)} for key in filter(lambda x: 'Element' in x, d1)]
我们将使用itertools.product
做一个笛卡尔积,考虑到elements
中存在的每个键和值的每个项目。
product = [list(it.product(d.keys(), *d.values())) for d in elements]
使用zip
,我们排列数据并将它们隐藏在字典中。 最后我们在new_df1
中创建"Elements"
键
elements_list = [dict(t) for index, t in enumerate(list(zip(*product)))] new_d1["Elements"] = elements_list print(new_d1)
完整代码:
import itertools as it
new_d1 = {key: d1.get(key)[0] for key in filter(lambda x: 'Element' not in x, d1)}
elements = [{key: d1.get(key)} for key in filter(lambda x: 'Element' in x, d1)]
product = [list(it.product(d.keys(), *d.values())) for d in elements]
elements_list = [dict(t) for index, t in enumerate(list(zip(*product)))]
new_d1["Elements"] = elements_list
Output:
{'Elements': [{'Element 1': '1', 'Element2': '1'},
{'Element 1': '2', 'Element2': '2'},
{'Element 1': '3', 'Element2': '3'}],
'Name': 'ABC',
'Number': '123'}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.