python - 从带有具有列表值的键的字典创建一个新的字典列表

标签 python list dictionary

我有一个字典,其中一个键的值为列表

example = {"a":1,"b":[1,2]}

我正在尝试解压 example["b"] 并使用单独的 example["b"] 值创建相同字典的列表。

output = [{"a":1,"b":1},{"a":1,"b":2}]

我尝试使用 for 循环来理解 dict 列表的解包和重建,但我看到了一个奇怪的行为 - 可能是我在这里遗漏了一些简单的东西......

iter = example.get("b")

new_list = []

for p in iter:
    print(f"p is {p}")
    tmp_dict = example
    tmp_dict["b"] = p
    print(tmp_dict)
    new_list.append(tmp_dict)

print(new_list)

输出

p is 1
{'a': 1, 'b': 1}
p is 2
{'a': 1, 'b': 2}
[{'a': 1, 'b': 2}, {'a': 1, 'b': 2}]

为什么列表中的第一个字典被分配为 example["b"] = 2 尽管第一个 print() 显示 p 是 1

最佳答案

Why is the first dict in the list gets assigned with example["b"] = 2 although the first print() shows that p is 1

因为它们都是相同的字典:example。如果您在循环内print(id(tmp_dict)),您可以看到这一点,并且您将看到它始终是同一个对象。请参阅What is the id( ) function used for? (这是一个 python 2 问题,但也适用于 python 3)

如果您想保留代码,只需从 example 创建一个新字典并将其分配给 tmp_dict 即可。请参阅How to copy a dictionary and only edit the copy

tmp_dict = example.copy()

虽然这基本上复制了整个字典只是为了丢弃 b 键,所以你可以简单地这样做:

tmp_dict = {"a": example["a"]}

请注意,不建议使用 iter 作为变量名称,因为 iter 已经 means something in python


相反,这是一种适用于所有情况的通用方法,无需对任何键进行硬编码。 让我们首先创建一个临时字典,其中所有值都是列表。

temp = {k: v if isinstance(v, list) else [v] for k, v in example.items()}

这使我们能够以列表的形式获取 temp 字典中所有值的列表。

我们想要这个 temp 字典中所有值的乘积。为此,我们可以使用 itertools.product 函数和 unpack我们的列表列表及其参数。

在每次迭代中,生成的元组将具有 temp 字典的每个键一个值,因此我们需要做的就是 zip与我们的元组一起使用,并从这些键值对中创建一个字典。这给了我们列表元素!

import itertools

keys = list(temp.keys())
vals = list(temp.values())

result = []

for vals_product in itertools.product(*vals):
    d = dict(zip(keys, vals_product))
    result.append(d)

这给出了所需的结果:

[{'a': 1, 'b': 1}, {'a': 1, 'b': 2}]

这甚至适用于具有更多键的示例:

example = {'a': 1, 'b': [1, 2], 'c': [1, 2, 3]}

给出:

[{'a': 1, 'b': 1, 'c': 1},
 {'a': 1, 'b': 1, 'c': 2},
 {'a': 1, 'b': 1, 'c': 3},
 {'a': 1, 'b': 2, 'c': 1},
 {'a': 1, 'b': 2, 'c': 2},
 {'a': 1, 'b': 2, 'c': 3}]

关于python - 从带有具有列表值的键的字典创建一个新的字典列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74106192/

相关文章:

html - 水平对齐不同高度的列表组(Bootstrap 3)

java - 我可以展平多深度自引用实体吗?

静态函数变量的 Pythonic 方式(小范围,单一初始化)?

python - 在列表中查找特定的子列表

ios - 如何在一行中没有键的情况下检查字典数组中的值

ios - TableView 单元格内的 UIButton 操作句柄

python - 在一个 barplot 中绘制字典字典

python - Django 在变量末尾添加新行,而 Flask 没有

python - 使用 Python Base64 压缩 GAE Blob 图像?

php - Python 中的 API 调用身份验证(工作 PHP 示例)