【问题标题】:stumped getting key value from a comprehension难以从理解中获得关键价值
【发布时间】:2019-03-22 01:07:31
【问题描述】:

我试图弄清楚如何从几乎有效的理解中获取值。从这个数据..

{'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 版本只是因为它更容易理解并且性能更好。顺便说一句,即使它有值也必须丢弃岩石,所以我无法绕过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
>>>

【问题讨论】:

    标签: python dictionary list-comprehension dictionary-comprehension


    【解决方案1】:

    您可以使用生成器表达式输出主dict值的子dict的项目,并使用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']}}
    

    【讨论】:

      【解决方案2】:

      只需要将dict 中的list 设置为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']}}
      

      【讨论】:

      • 哦,这个解决方案的另一个改写试图让它更快令我惊讶的是仍然比 itertools 版本慢。 >>> timeit.timeit( "dict(v for d in data.values() for v in data.items() if v[0] != 'rock')" , setup="from __main__ import data")2.7223397847265005
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-06
      • 2021-12-05
      • 1970-01-01
      • 2020-01-12
      • 2014-03-28
      • 1970-01-01
      • 2023-03-24
      相关资源
      最近更新 更多