繁体   English   中英

来自列表字典的字典

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

我强烈建议不要尝试在一行中做所有事情。 如果您有任何分支逻辑或嵌套循环,它并不总是更有效,而且几乎总是不太可读。

给定您的字典,我们可以将NameNumberpop()到我们的新字典中。 然后

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'}]}  

我将逐步解释:

  1. 我们构建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)}
  2. 我们构建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)]
  3. 我们将使用itertools.product做一个笛卡尔积,考虑到elements中存在的每个键和值的每个项目

     product = [list(it.product(d.keys(), *d.values())) for d in elements]
  4. 使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM