难以从理解中获得关键价值
stumped getting key value from a 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 版本只是因为它更容易理解并且性能稍微好一点。顺便说一句,岩石必须被丢弃,即使它有价值,所以我无法绕过 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
>>>
只需要将 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.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']}}}
这个returns:
{'gold3': {'data': ['g3']}, 'gold2': {'data': ['g2']}, 'gold1': {'data': ['g1']}}
我试图弄清楚如何从几乎有效的理解中获取价值。从这个数据..
{'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
>>>
只需要将 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.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']}}}
这个returns:
{'gold3': {'data': ['g3']}, 'gold2': {'data': ['g2']}, 'gold1': {'data': ['g1']}}