我有这样一条可以随时改变的道路:
'#/path/to/key'
路径的各个部分没有定义,因此该值也是合适的
'#/this/is/a/longer/path'
我在'/'处拆分这个键,所以我得到
['#', 'path', 'to', 'key']
我需要在这条路径上找到键,假设我的dict是exp,我需要到这里:
exp['path']['to']['key']
我怎么可能知道怎么找到这把钥匙?
57hvy0tb1#
用递归法卢克。
def deref_multi(data, keys): return deref_multi(data[keys[0]], keys[1:]) \ if keys else data last = deref_multi(exp, ['path','to','key'])
UPDATE:已经5年多了,是时候更新了,这次没有使用递归(它可能比Python内部循环使用更多的资源),使用你更容易理解(也更容易维护)的方法:
from functools import reduce def deref_multi(data, keys): return reduce(lambda d, key: d[key], keys, data)
6pp0gazn2#
我建议您使用python-benedict,它是一个python dict子类,具有完全的keypath支持和许多实用方法。您只需要发布现有的命令:
python-benedict
exp = benedict(exp) # now your keys can be dotted keypaths too exp['path.to.key']
这里的库和文档:https://github.com/fabiocaccamo/python-benedict注:本人是本项目的作者
ryhaxcpt3#
def get_key_by_path(dict_obj, path_string): path_list = path_string.split('/')[1:] obj_ptr = dict_obj for elem in path_list: obj_ptr = obj_ptr[elem] return obj_ptr
9bfwbjaz4#
这里有一些很好的答案,但是没有一个解释路径不正确或者路径在某个点导致不可订阅的东西。下面的代码可能会允许你在处理这些情况时有更多的回旋余地,而其他代码到目前为止只会抛出错误或有意外的行为。
path = '#/path/to/key' exp = {'path' : { 'to' : { 'key' : "Hello World"}}} def getFromPath(dictionary, path): curr = dictionary path = path.split("/")[1:] # Gets rid of '#' as it's uneccessary while(len(path)): key = path.pop(0) curr = curr.get(key) if (type(curr) is not dict and len(path)): print("Path does not exist!") return None return curr print(getFromPath(exp, path)) #Your value
m4pnthwp5#
>>> exp = {'path': {'to': {'key': 42}}} >>> my_key = exp >>> for i in '#/path/to/key'.split('/')[1:]: >>> my_key = my_key[i] >>> print(my_key) 42
不过,我有点好奇你是怎么拿到这样的诏书的
pkbketx96#
假设你的意思是你的数组['#', 'path', 'to', 'key']有索引,从索引1开始,你可以从第二个开始迭代列表中的每一项,并且在每一次迭代中挖掘得更深。例如,在Python 3中可以这样做。
1
def get_key_from_path(exp, path): """Returns the value at the key from <path> in <exp>. """ cur = exp for dir in path[1:]: cur = exp[dir] return cur
8i9zcol27#
使用函数工具代替递归:
# Define: from functools import partial, reduce deref = partial(reduce, lambda d, k: d[k]) # Use: exp = {'path': {'to': {'key': 42}}} deref(('path', 'to', 'key'), exp)
3岁的问题,我知道...我只是真的很喜欢functools。
7条答案
按热度按时间57hvy0tb1#
用递归法卢克。
UPDATE:已经5年多了,是时候更新了,这次没有使用递归(它可能比Python内部循环使用更多的资源),使用你更容易理解(也更容易维护)的方法:
6pp0gazn2#
我建议您使用
python-benedict
,它是一个python dict子类,具有完全的keypath支持和许多实用方法。您只需要发布现有的命令:
这里的库和文档:https://github.com/fabiocaccamo/python-benedict
注:本人是本项目的作者
ryhaxcpt3#
9bfwbjaz4#
这里有一些很好的答案,但是没有一个解释路径不正确或者路径在某个点导致不可订阅的东西。下面的代码可能会允许你在处理这些情况时有更多的回旋余地,而其他代码到目前为止只会抛出错误或有意外的行为。
m4pnthwp5#
不过,我有点好奇你是怎么拿到这样的诏书的
pkbketx96#
假设你的意思是你的数组
['#', 'path', 'to', 'key']
有索引,从索引1
开始,你可以从第二个开始迭代列表中的每一项,并且在每一次迭代中挖掘得更深。例如,在Python 3中可以这样做。
8i9zcol27#
使用函数工具代替递归:
3岁的问题,我知道...我只是真的很喜欢functools。