簡體   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