如何从具有不同长度列表的字典中创建字典列表

Posted

技术标签:

【中文标题】如何从具有不同长度列表的字典中创建字典列表【英文标题】:How to create a list of dictionaries from a dictionary with lists of different lengths 【发布时间】:2020-01-11 00:50:40 【问题描述】:

我想从每个列表中创建一个具有相同索引元素的字典列表。

我有这本词典:

d = 'name': ['bob', 'john', 'harry', 'mary'], 
     'age': [13, 19, 23], 
     'height': [164, 188], 
     'job': ['programmer']

想要的输出是:

d2 = ['name': 'bob', 'age': 13, 'height': 164, 'job': 'programmer', 
      'name': 'john', 'age': 19, 'height': 188, 
      'name': 'harry', 'age': 23,
      'name': 'mary']

我尝试过这样的事情:

d2 = [dict(zip(d, t)) for t in zip(*d.values())]

但我的输出是:

d2 = ['name': 'bob', 'age': 13, 'height': 164, 'job': 'programmer']

我认为这是因为列表的长度不同。

【问题讨论】:

【参考方案1】:

您可以使用itertools.zip_longest 并过滤掉None 值:

from itertools import zip_longest

[x: y for x, y in zip(d, t) if y is not None for t in zip_longest(*d.values())]
# ['name': 'bob', 'age': 13, 'height': 164, 'job': 'programmer', 
#  'name': 'john', 'age': 19, 'height': 188, 
#  'name': 'harry', 'age': 23, 
#  'name': 'mary']

【讨论】:

【参考方案2】:

您可以在这里使用zip_longest

from itertools import zip_longest

keys = d.keys()

d2 = [
    k: v for k, v in zip(keys, vs) if v is not None
    for vs in zip_longest(*d.values())
]

如果值也可以是None,我们可以通过使用虚拟值来规避它:

from itertools import zip_longest

keys = d.keys()
dummy = object()

d2 = [
    k: v for k, v in zip(keys, vs) if v is not dummy
    for vs in zip_longest(*d.values(), fillvalue=dummy)
]

这里的 dummy 是一个对象,我们确信它不属于 d 中的项目(因为我们在构造 d 之后构造它)。通过使用is 比较,我们可以知道该值是否是“填充值”。

这会给我们:

>>> d2
['name': 'bob', 'age': 13, 'height': 164, 'job': 'programmer', 'name': 'john', 'age': 19, 'height': 188, 'name': 'harry', 'age': 23, 'name': 'mary']

【讨论】:

【参考方案3】:

这是另一种方法:

d = 'name': ['bob', 'john', 'harry', 'mary'], 'age': [13, 19, 23], 'height': [164, 188], 'job': ['programmer']
m = max(map(len, d.values()))
d1 = k : (v if len(v)==m else v+['']*(m-len(v))) for k,v in d.items()
d2 = [k:v for k,v in zip(d, t) if v for t in zip(*d1.values())]
print(d2)

输出

['height': 164, 'age': 13, 'job': 'programmer', 'name': 'bob', 'height': 188, 'age': 19, 'name': 'john', 'age': 23, 'name': 'harry', 'name': 'mary']

【讨论】:

【参考方案4】:

一个不使用 zip_longest 的简单解决方案,记录一下:

d = 'name': ['bob', 'john', 'harry', 'mary'], 'age': [13, 19, 23], 'height': [164, 188], 'job': ['programmer']

recordset = [k: v[i] for k, v in d.items() if i < len(v) for i in range(max([len(l) for l in d.values()]))]

print(recordset)  # >> ['name': 'bob', 'age': 13, 'height': 164, 'job': 'programmer', 
                        'name': 'john', 'age': 19, 'height': 188, 
                        'name': 'harry', 'age': 23, 
                        'name': 'mary']

【讨论】:

【参考方案5】:

只需保留所有内容并添加此导入语句:

从 itertools 导入 zip_longest 为 zip

【讨论】:

以上是关于如何从具有不同长度列表的字典中创建字典列表的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Python 中不同长度的列表列表中创建数据框?

从不同长度的元组列表的字典中创建 Pandas DataFrame

如何在python中反转字典并从重复的键值中创建一个列表

一个班轮:从列表中创建一个字典,索引为键

从字典列表中创建NumPy记录数组的最简单方法?

从字典列表中创建嵌套的 json 对象