难于从理解中获得关键价值

时间:2019-03-22 01:07:31

标签: python dictionary list-comprehension dictionary-comprehension

我正试图弄清如何从理解中获取价值,这几乎是可行的。从这些数据..

{'rock': {}, 'coal1': {'gold1': {'data': ['g1']}}, 'coal2': {'gold3': {'data': ['g3']}, 'gold2': {'data': ['g2']}}}

..我试图将金钥匙数据提取到简单的字典中。即{ gold : {'data' : [...]} }个项目的字典实际上从数据中删除了煤密匙。

换句话说,就是这个..

{
  "coal2": {
    "gold3": {
      "data": [
        "g3"
      ]
    },
    "gold2": {
      "data": [
        "g2"
      ]
    }
  },
  "coal1": {
    "gold1": {
      "data": [
        "g1"
      ]
    }
  },
  "rock": {}
}

采用这种格式

{
  "gold3": {
    "data": [
      "g3"
    ]
  },
  "gold1": {
    "data": [
      "g1"
    ]
  },
  "gold2": {
    "data": [
      "g2"
    ]
  }
}

那几乎可以正常工作。这摆脱了岩石。

>>> {k:d for k,d in data.items() if k != 'rock'}
{'coal2': {'gold3': {'data': ['g3']}, 'gold2': {'data': ['g2']}}, 'coal1': {'gold1': {'data': ['g1']}}}

获取值摆脱了煤键。

>>> [v for v in {k:d for k,d in data.items() if k != 'rock'}.values()]
[{'gold3': {'data': ['g3']}, 'gold2': {'data': ['g2']}}, {'gold1': {'data': ['g1']}}]

但是我不知道如何从中得到

>>> for i in [v for v in {k:d for k,d in data.items() if k != 'rock'}.values()] : print(i)
...
{'gold3': {'data': ['g3']}, 'gold2': {'data': ['g2']}}
{'gold1': {'data': ['g1']}}

为所需的结构。如果所有这些都可以通过理解来完成,那就太好了。有人知道如何做到这一点吗?

编辑: 这两个答案都很棒,我希望我能接受。我不喜欢导入任何东西,但是我接受@blhsing itertools版本,只是因为它更易于理解并且性能稍差。 BTW岩石即使具有值也必须被丢弃,因此我无法绕过if k != 'rock'。所以这里是结果,...谢谢大家。

>>> import timeit
>>> data = {'rock': {'type':'pebble'}, 'coal1': {'gold1': {'data': ['g1']}}, 'coal2': {'gold3': {'data': ['g3']}, 'gold2': {'data': ['g2']}}}
>>> timeit.timeit( "dict(kv for x in (v for v in {k:d for k,d in data.items() if k != 'rock'}.values()) for kv in x.items())" ,  setup="from __main__ import data")            
2.6714617270044982
>>>
>>> timeit.timeit( "dict(chain.from_iterable(g.items() for g in {k:d for k,d in data.items() if k != 'rock'}.values()))" , setup="from __main__ import data; from itertools import chain")
2.22612579818815
>>>

2 个答案:

答案 0 :(得分:1)

只需将list中的dict更改为dict(通过添加第二行来完成代码的编写)

l=[v for v in {k:d for k,d in d.items() if k != 'rock'}.values()] # here is your own code 
newd=dict(kv for x in l for kv in x.items())
newd
Out[431]: 
{'gold1': {'data': ['g1']},
 'gold2': {'data': ['g2']},
 'gold3': {'data': ['g3']}}

单行

dict(v for d in d.values() for v in d.items()) # d is your dict
Out[436]: 
{'gold1': {'data': ['g1']},
 'gold2': {'data': ['g2']},
 'gold3': {'data': ['g3']}}

答案 1 :(得分:1)

您可以使用生成器表达式来输出主字典值的子字典的项目,并使用itertools.chain.from_iterable联接这些项目,并将其传递给dict构造函数:

from itertools import chain
dict(chain.from_iterable(g.items() for g in d.values()))

所以给定:

d = {'rock': {}, 'coal1': {'gold1': {'data': ['g1']}}, 'coal2': {'gold3': {'data': ['g3']}, 'gold2': {'data': ['g2']}}}

这将返回:

{'gold3': {'data': ['g3']}, 'gold2': {'data': ['g2']}, 'gold1': {'data': ['g1']}}