python - 迭代字典列表和解包
python - iterating list of dictionaries and unpacking
给出简单字典的简单列表
lst = [{'key1': 1}, {'key2': 2}, {'key3': 3}]
我想找到使用此处未详述的方法计算得出的最小值的字典。
我的第一个想法是迭代列表以逐个字典检查字典,但这失败了:
for k, v in [x.items() for x in lst]:
print(k, v)
结果 ValueError(以及使用生成器而不是列表):
for k, v in [x.items() for x in lst]:
ValueError: not enough values to unpack (expected 2, got 1)
然而,
for x in lst:
for k, v in x.items():
print(k, v)
产量
key1 1
key2 2
key3 3
不出所料。我假设所有方法都按预期工作(除非 PEBKAC),但为什么它不能使用列表理解?有没有人能赐教一下?
编辑:我使用 python 3 并且我知道 items() 会产生 dict_view 但我不明白为什么逻辑不起作用。
您缺少一个迭代级别。
通常,dict 有不止一对 key/value。 dict.items()
将整个字典转换为 (key, value)
形式的元组序列。在你的例子中,每个字典只有一个项目,但 items()
的结果仍然是元组的元组。
如果打印 [x.items() for x in lst]
的结果,您会看到结果是 dict_view
项的列表;其中每一个本身都可以迭代。
尝试逐步解压您的 lst
以了解其构造方式。
>>> in: lst[0].items()
>>> out: [('key1', 1)]
您的结果(等于您在列表理解中的 x.items()
表达式)是 另一个包含您的 k 和 v 元组的列表。元组是元素此列表中的索引 0(也是唯一的元素)。所以你需要像
for k, v in [x.items()[0] for x in lst]:
print(k, v)
您可以像这样遍历字典的键值对:-
for k, v in dic.items():
print(k, v)
上面的代码所做的是首先将字典转换为元组列表,然后在迭代到 k、v 时一个一个地解包,就像:-
k, v = (k, v) # Tuple unpacking.
现在在你的情况下,考虑这个代码:-
z = [x.items() for x in lst]
print(z)
输出为
[dict_items([('key1', 1)]), dict_items([('key2', 2)]), dict_items([('key3', 3)])]
即元组列表的列表。
那么,让我们将您的代码重写为:-
for k, v in z:
print(k, v)
其中 z 是元组列表的列表。
在每次迭代中,它从父列表中选取一个列表(仅包含一个元素),然后尝试:-
k, v = [(key, value)] # a list of only one tuple to be unpacked against two variables and hence the failure.
希望对您有所帮助。
您可以在列表理解中添加一级缩进(如@DanielRoseman 建议的那样),而不是使用 dict_view
的第一个元素:
for k, v in [(k, v) for x in lst for (k, v) in x.items()]:
print(k, v)
产量
key1 1
key2 2
key3 3
符合预期。
给出简单字典的简单列表
lst = [{'key1': 1}, {'key2': 2}, {'key3': 3}]
我想找到使用此处未详述的方法计算得出的最小值的字典。 我的第一个想法是迭代列表以逐个字典检查字典,但这失败了:
for k, v in [x.items() for x in lst]:
print(k, v)
结果 ValueError(以及使用生成器而不是列表):
for k, v in [x.items() for x in lst]:
ValueError: not enough values to unpack (expected 2, got 1)
然而,
for x in lst:
for k, v in x.items():
print(k, v)
产量
key1 1
key2 2
key3 3
不出所料。我假设所有方法都按预期工作(除非 PEBKAC),但为什么它不能使用列表理解?有没有人能赐教一下?
编辑:我使用 python 3 并且我知道 items() 会产生 dict_view 但我不明白为什么逻辑不起作用。
您缺少一个迭代级别。
通常,dict 有不止一对 key/value。 dict.items()
将整个字典转换为 (key, value)
形式的元组序列。在你的例子中,每个字典只有一个项目,但 items()
的结果仍然是元组的元组。
如果打印 [x.items() for x in lst]
的结果,您会看到结果是 dict_view
项的列表;其中每一个本身都可以迭代。
尝试逐步解压您的 lst
以了解其构造方式。
>>> in: lst[0].items()
>>> out: [('key1', 1)]
您的结果(等于您在列表理解中的 x.items()
表达式)是 另一个包含您的 k 和 v 元组的列表。元组是元素此列表中的索引 0(也是唯一的元素)。所以你需要像
for k, v in [x.items()[0] for x in lst]:
print(k, v)
您可以像这样遍历字典的键值对:-
for k, v in dic.items():
print(k, v)
上面的代码所做的是首先将字典转换为元组列表,然后在迭代到 k、v 时一个一个地解包,就像:-
k, v = (k, v) # Tuple unpacking.
现在在你的情况下,考虑这个代码:-
z = [x.items() for x in lst]
print(z)
输出为
[dict_items([('key1', 1)]), dict_items([('key2', 2)]), dict_items([('key3', 3)])]
即元组列表的列表。
那么,让我们将您的代码重写为:-
for k, v in z:
print(k, v)
其中 z 是元组列表的列表。 在每次迭代中,它从父列表中选取一个列表(仅包含一个元素),然后尝试:-
k, v = [(key, value)] # a list of only one tuple to be unpacked against two variables and hence the failure.
希望对您有所帮助。
您可以在列表理解中添加一级缩进(如@DanielRoseman 建议的那样),而不是使用 dict_view
的第一个元素:
for k, v in [(k, v) for x in lst for (k, v) in x.items()]:
print(k, v)
产量
key1 1
key2 2
key3 3
符合预期。