python - 迭代字典列表和解包

时间:2017-09-21 13:53:46

标签: python python-3.x list-comprehension argument-unpacking

给出一个简单的词典列表

lst = [{'key1': 1}, {'key2': 2}, {'key3': 3}]

我想找到一个dict,它产生使用此处未详述的方法评估的最小值。 我的第一个想法是迭代列表以通过dict检查dict,但这失败了:

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,但我不明白为什么逻辑不起作用。

4 个答案:

答案 0 :(得分:7)

你错过了一个迭代级别。

通常,dicts有多个键/值对。 dict.items()将整个字典转换为(key, value)形式的元组序列。在您的情况下,每个字典只有一个项目,但items()的结果仍然是元组的元组。

如果您打印[x.items() for x in lst]的结果,您会看到结果是dict_view个项目的列表;其中每一个都可以自己迭代。

答案 1 :(得分:4)

您可以在列表理解中添加一级缩进(如@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

正如所料。

答案 2 :(得分:1)

尝试逐步解压缩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)

答案 3 :(得分:0)

您可以迭代字典的键值对,如下所示: -

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.

我希望这很有帮助。