获取字符值,其中部分键位于字符串中

时间:2016-04-26 20:08:16

标签: python string python-3.x dictionary

拿一本字典

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"]位中避免硬编码的位置,以防它发生变化。

2 个答案:

答案 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()]