繁体   English   中英

列表理解以扁平化词典字典

[英]List Comprehension to Flatten a Dictionary of Dictionaries

我有字典词典:

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)。 我以为我写的理解只会在适当的字典中寻找键。

我已经看到了这种解决方案 ,可以解决所有嵌套词典的问题。 我也知道我可以通过命令循环强行使用它。 我只是想了解为什么列表理解不能按我编写的方式工作。

您要遍历值的值:

[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]

正如厄尔舍比尼所说,

[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]解释for pair in my_dict[letter]并且除非已经定义了letter ,否则对此没有任何意义。 如果letter先前被定义为b (运行先前的列表理解后剩下的值),则它将对设置为my_dict['b']的键。 然后,它for letter in my_dict查找for letter in my_dict并将字母设置为'a''b' 然后,它尝试评估第一部分my_dict[letter][pair] ,但它使用了b的键,因此当letter取值为'a'时,这将不起作用。

在下面,我运行您的理解并获取NameError ,然后运行另一个理解,该副作用会设置letter的值,然后再次运行您的相同理解并获取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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM