拿一本字典
dict = {"word":{"a":{"b":2}}}
我想得到值2。
要访问此内容,我可以执行此操作dict["word"]["a"]["b"]
但是我想知道我可以在字符串中包含部分键(["a"]["b]
部分)
并参考类似这样的内容
string = "[\"a\"][\"b\"]"
dict["word"]string
或类似的东西
我知道这种语法不正确但可以这样做吗?
Python 3.x中的
编辑: 一个更好的dict示例可能就是这个
dict = {
"word":{"a":{"b":2}}
"hello":{"a":{"b":1}}
"mouse":{"a":{"b":5}}
}
如何在每种情况下获得b的值?您希望在密钥的["a"]["b"]
位中避免硬编码的位置,以防它发生变化。
答案 0 :(得分:3)
不要使用dict
作为变量名,因为它会影响内置函数。
其中一种方法是使用re
module。这里的主要思想是你使用正则表达式来找出键。获得密钥列表后,提取数据是一项简单的任务。
>>> d = {"word":{"a":{"b":2}}}
>>> s = '["a"]["b"]'
>>> import re
>>> keys = re.findall(r'\["(.+?)"\]',s)
>>> d["word"][keys[0]][keys[1]]
2
如果有很多密钥,那么您可以使用functools
包中的reduce
。 (正如JonClements在comment中提到的那样)
>>> import functools
>>> functools.reduce(dict.__getitem__, keys, d['word'])
2
对于较长的dicts,您可以使用list comprehension
>>> d = {
... "word":{"a":{"b":2}},
... "hello":{"a":{"b":1}},
... "mouse":{"a":{"b":5}}
... }
>>> [functools.reduce(dict.__getitem__, keys, d[i]) for i in d]
[2, 5, 1]
但请注意,由于字典键的无序性质,列表的输出可能与预期不符。更好的方法是将完整字典缩减为新字典(使用字典理解),如
>>> {i:functools.reduce(dict.__getitem__, keys, d[i]) for i in d}
{'word': 2, 'mouse': 5, 'hello': 1}
答案 1 :(得分:2)
最好的方法是编写自己要解析的语法。你必须使用一个永远不会出现在密钥中的字符,一个流行的例子是.
,但类似的,$
,|
也可以。
def get(d, key):
kp = key.split('.')
for k in kp:
d = d[k]
return d
d = {'a': {'b': 2}}
get(d, 'a.b')
>>> 2
编辑更新问题:
那么您是否希望能够在每种情况下获得a.b值的列表?如果是这样,你仍然可以使用上面的方法
d = {
"word":{"a":{"b":2}},
"hello":{"a":{"b":1}},
"mouse":{"a":{"b":5}},
}
# nesting calls to get just to show it is flexible like that
[get(get(d, k), 'a.b') for k in d.keys()]
# if you wanted to generate a dict of {"word": val} it would look like this
{k:get(get(d, k), 'a.b') for k in d.keys()}
如果你的变量部分在中间
,它甚至可以工作d = {
"x": {"word":{"a":{"b":2}}},
"x": {"hello":{"a":{"b":1}}},
"x": {"mouse":{"a":{"b":5}}},
}
# using more calls to get just to show it is flexible like that
[get(get(d, 'x.'+k), 'a.b') for k in get(d, 'x').keys()]