繁体   English   中英

将带有列表的字典转换为字典列表

[英]Converting a dictionary with lists into a list of dictionaries

我有这本字典,其中包含列表,因为它们是键的值。

d = {'n': ['a', 'b', 'x'], 'a': [1, 2, 3], 'p': ['123', '321', '456']}

我想转换成这样的字典列表

[{'n':'a','a':1,'p':'123'},{'n':'b','a':2,'p':'321'},{ 'n':'x','a':3,'p':'456'}]

我目前的解决方案是,

the_kv = d.items()
f = {}
c = {}
e = {}

f_c_e = []
for i, j in the_kv:
    f[i] = j[0]
    c[i] = j[1]
    e[i] = j[2]

f_c_e.append(f)
f_c_e.append(c)
f_c_e.append(e)
print(f_c_e)

但我想知道是否有更有效的方法,而不是创建单独的 dicts 然后将它们附加到列表中。

使用zip

[dict(zip(d, vals)) for vals in zip(*d.values())]

结果:

[{'n': 'a', 'a': 1, 'p': '123'}, {'n': 'b', 'a': 2, 'p': '321'}, {'n': 'x', 'a': 3, 'p': '456'}]

用:

res = [dict(v) for v in zip(*[[(key, value) for value in values] for key, values in d.items()])]
print(res)

输出

[{'n': 'a', 'a': 1, 'p': '123'}, {'n': 'b', 'a': 2, 'p': '321'}, {'n': 'x', 'a': 3, 'p': '456'}]

一种更简单的替代方法是:

result = [{} for _ in range(len(d))]
for key, values in d.items():
    for i, value in enumerate(values):
        result[i][key] = value

print(result)

输出(替代)

[{'n': 'a', 'a': 1, 'p': '123'}, {'n': 'b', 'a': 2, 'p': '321'}, {'n': 'x', 'a': 3, 'p': '456'}]

好问题。 从一种数据类型到另一种数据类型的转换在开发或竞争性编程中都是必不可少的。

它可以通过多种方法完成,我将在下面解释我所知道的两种方法:

方法#1 :使用列表推导我们可以使用列表推导作为单行替代来执行各种简单的任务,提供可读性和更简洁的代码。 我们可以遍历每个字典元素并相应地继续构造字典列表。

# Python3 code to demonstrate 
# to convert dictionary of list to 
# list of dictionaries
# using list comprehension
  
# initializing dictionary
test_dict = { "Rash" : [1, 3], "Manjeet" : [1, 4], "Akash" : [3, 4] }
  
# printing original dictionary
print ("The original dictionary is : " + str(test_dict))
  
# using list comprehension
# to convert dictionary of list to 
# list of dictionaries
res = [{key : value[i] for key, value in test_dict.items()}
         for i in range(2)]
  
# printing result
print ("The converted list of dictionaries " +  str(res))

方法#2 :使用 zip() 这种方法使用了两次 zip 函数,第一次是我们需要将所有列表的特定索引值压缩为一个,第二次是为了获取特定索引的所有值并使用相应的键对其进行压缩。

# Python3 code to demonstrate
# to convert dictionary of list to
# list of dictionaries
# using zip()

# initializing dictionary
test_dict = { "Rash" : [1, 3], "Manjeet" : [1, 4], "Akash" : [3, 4] }

# printing original dictionary
print ("The original dictionary is : " + str(test_dict))

# using zip()
# to convert dictionary of list to
# list of dictionaries
res = [dict(zip(test_dict, i)) for i in zip(*test_dict.values())]

# printing result
print ("The converted list of dictionaries " + str(res))

输出

The original dictionary is : {‘Rash’: [1, 3], ‘Manjeet’: [1, 4], ‘Akash’: [3, 4]}
The converted list of dictionaries [{‘Rash’: 1, ‘Manjeet’: 1, ‘Akash’: 3}, {‘Rash’: 3, ‘Manjeet’: 4, ‘Akash’: 4}]

让我们一步一步地解决这个问题。

核心困难在于我们有一系列列表:

['a', 'b', 'x']
[1, 2, 3]
['123', '321', '456']

并且我们想要产生由每个列表的元素 0、每个列表的元素 1 等组成的序列(这些序列中的每一个都包含输出字典的所有值。)也就是说,我们想要转置列表,其中正是内置zip的用途:

# Feed the generator to `list` to unpack and view them
list(zip(
    ['a', 'b', 'x'],
    [1, 2, 3],
    ['123', '321', '456']
))

现在我们可以勾勒出一个完整的流程:

  1. 获取输入的键和值(以相同的顺序)。
  2. 转置值。
  3. 对于转置值中的每个序列,将该序列与键匹配以生成新的字典。

前两部分很简单:

keys, value_lists = d.keys(), d.values()
# Since the .values() are a sequence, while `zip` accepts multiple
# arguments, we need to use the `*` operator to unpack them as
# separate arguments.
grouped_values = zip(*value_lists)

最后,让我们首先弄清楚如何从new_values一个创建单个结果字典。 从一堆键值对中制作 dict 很容易 - 我们可以将其直接提供给dict 然而,我们有一对序列——原始的.keys()和来自zip的结果。 显然,解决方案是再次zip ——我们可以创建一个简单的辅助函数来确保一切都尽可能清晰:

def new_dict(keys, values):
    return dict(zip(keys, values))

然后我们需要做的就是重复应用该函数

new_dicts = [new_dict(keys, values) for values in grouped_values]

为了炫耀,将所有内容与短名称内联给出:

new_dicts = [dict(zip(d.keys(), v)) for v in zip(*d.values())]

这几乎正​​是 Jab 的答案(请注意,迭代字典给出了键,因此您可以直接将d而不是d.keys()传递给zip因为zip只会对其进行迭代)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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