简体   繁体   English

来自列表字典的字典

[英]dict from a dict of list

I have a Python dictionary with following format:我有一个 Python 字典,格式如下:

d1 = {'Name':['ABC'], 'Number':['123'], 'Element 1':['1', '2', '3'],
      'Element2':['1','2','3']}

Expected output:预期 output:

{'Name': 'ABC', 'Number': '123',
 'Elements': [{'Element 1': '1', 'Element2': '1'},
              {'Element 1': '2', 'Element2': '2'},
              {'Element 1': '3', 'Element2': '3'}]

I have tried the following:我尝试了以下方法:

[{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()]))]

but getting this result:但得到这个结果:

[{'Name': 'ABC', 'Number': '123', 'Element 1': '1', 'Element 2': '1'},
 {'Element 1': '2', 'Element 2': '2'},
 {'Element 1': '3', 'Element 2': '3'}]

How can I go from here?我怎么能从这里 go ?

I strongly recommend not trying to do everything in one line.我强烈建议不要尝试在一行中做所有事情。 It's not always more efficient, and almost always less readable if you have any branching logic or nested loops.如果您有任何分支逻辑或嵌套循环,它并不总是更有效,而且几乎总是不太可读。

Given your dict, we can pop() the Name and Number keys into our new dict.给定您的字典,我们可以将NameNumberpop()到我们的新字典中。 Then然后

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

Then, we zip all remaining values in the dictionary, and add them to a new list:然后,我们 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'}]

And finally, assign that to output["Elements"]最后,将其分配给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'}]}

Since you don't want to hardcode the first two keys,由于您不想硬编码前两个键,

for k, v in d1.items():
    if "element" not in k.lower():
        output[k] = v

Or as a dict-comprehension:或作为字典理解:

output = {k: v for k, v in d1.items() if "element" not in k.lower()}

use a list of tuples to create the elements list of dictionaries.使用元组列表来创建字典的元素列表。 Use Convert to build your dictionary item from the tuple.使用 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: output:

 {'Name': 'ABC', 'Number': '123', 'Elements': [{'Element 1': '1'}, {'Element 1': '2'}, {'Element 1': '3'}, {'Element2': '1'}, {'Element2': '2'}, {'Element2': '3'}]}  

I'm going to explain step by step:我将逐步解释:

  1. We build new_d1 variable, that is the dictionary you expect as output and it's initialized as {'Name': 'ABC', 'Number': '123'} .我们构建new_d1变量,即您期望的字典 output 并且它被初始化为{'Name': 'ABC', 'Number': '123'} For achieving the above, we use comprehension notation taking into account the keys != 'Element'为了实现上述目的,我们使用理解符号,同时考虑到键!= 'Element'

     new_d1 = {key: d1.get(key)[0] for key in filter(lambda x: 'Element' not in x, d1)}
  2. We build elements variable, that's a list with the dictionaries matter for us, I mean, the dictionaries we have to manipulate to achieve the expected result.我们构建elements变量,这是一个包含字典的列表,对我们来说很重要,我的意思是,我们必须操纵字典才能达到预期的结果。 Then elements is [{'Element 1': ['1', '2', '3']}, {'Element2': ['1', '2', '3']}] .然后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. We are going to do a Cartesian product using itertools.product taking into account each key and each item of the values present in elements .我们将使用itertools.product做一个笛卡尔积,考虑到elements中存在的每个键和值的每个项目

     product = [list(it.product(d.keys(), *d.values())) for d in elements]
  4. Using zip , we arrange the data and covert them in dictionary.使用zip ,我们排列数据并将它们隐藏在字典中。 And finally we create "Elements" key in new_df1最后我们在new_df1中创建"Elements"

    elements_list = [dict(t) for index, t in enumerate(list(zip(*product)))] new_d1["Elements"] = elements_list print(new_d1)

Full code:完整代码:

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: 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