我有一本字典词典:
my_dict = {
'a': {(1,2): True,
(1,3): False},
'b': {(1,4): True,
(2,3): False}
}
字典总是这种形式,但每个“子”字典都有一组不同的密钥:my_dict['a'][(1,2)]
存在,但这并不意味着my_dict['b'][(1,2)]
也存在。
我想要一个布尔值的列表(没有特别的顺序):
[True, False, True, False]
我正在尝试使用单个列表理解来完成此任务:
[my_dict[letter][pair] for pair in my_dict[letter] for letter in my_dict]
这会引发错误:
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-142-dc1565efcdc8> in <module>()
6 }
7
----> 8 [my_dict[letter][pair] for pair in my_dict[letter] for letter in my_dict]
KeyError: (2, 3)
它似乎在my_dict ['a']和my_dict ['b']中寻找(2,3)。我认为我写的理解只会在相应的字典中查找键。
我见过this solution可以用来展平任何嵌套字典。我也知道我可以用强制循环来强制它。我只是想弄清楚为什么列表理解不像我写的那样工作。
答案 0 :(得分:5)
您希望遍历值的值:
[v for nested in outer.itervalues() for v in nested.itervalues()]
请注意,循环需要按照您嵌套的方式进行排序;外循环首先:
for nested in outer.itervalues():
for v in nested.itervalues():
# use v
你把订单搞砸了;您的代码仅提供KeyError
,因为您预先存在letter
全局。
演示:
>>> my_dict = {
... 'a': {(1,2): True,
... (1,3): False},
... 'b': {(1,4): True,
... (2,3): False}
... }
>>> [v for nested in my_dict.itervalues() for v in nested.itervalues()]
[True, False, False, True]
答案 1 :(得分:1)
正如埃尔谢比尼所说,
[my_dict[letter][pair] for letter in my_dict for pair in my_dict[letter]]
这也有效:
[little_dict[k] for little_dict in [my_dict[letter] for letter in my_dict] for k in little_dict]
两者都产生[True, False, False, True]
。
您想了解原始尝试不起作用的原因。
[my_dict[letter][pair] for pair in my_dict[letter] for letter in my_dict]
这个运行的唯一原因是你必须先前已经定义了letter
,也许是之前运行过一些类似理解的遗留定义。它首先尝试解释for pair in my_dict[letter]
,除非letter
已经定义,否则无法理解这一点。如果字母先前被定义为b
(运行上一个列表理解所留下的值),则它将对设置为my_dict['b']
的键。然后,它会查看for letter in my_dict
,并将字母设置为'a'
和'b'
。然后它会尝试评估第一部分my_dict[letter][pair]
,但是它使用的是b
中的键,因此当字母取值'a'
时,这将无效。
下面,我运用你的理解并获得NameError
,然后运行另一个理解,作为副作用设置letter
的值,然后我再次运行同样的理解并获得{{1} }。
KeyError
请注意,Python 2.6.9
>>> my_dict = {
... 'a': {(1,2): True,
... (1,3): False},
... 'b': {(1,4): True,
... (2,3): False}
... }
>>>
>>> [my_dict[letter][pair] for pair in my_dict[letter] for letter in my_dict]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'letter' is not defined
>>> letter
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'letter' is not defined
>>> [letter for letter in my_dict]
['a', 'b']
>>> letter
'b'
>>> [my_dict[letter][pair] for pair in my_dict[letter] for letter in my_dict]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: (2, 3)
>>>
仅在(意外)设置KeyError
的值后才会发生letter
。第一次运行会生成NameError
。