我有字符串值,
"a"
"a.b"
"b.c.d"
如何将它们转换为python字典变量,
a
a["b"]
b["c"]["d"]
字符串的第一部分(在点之前)将成为字典名称,其余的子字符串将成为字典键
答案 0 :(得分:3)
eval
在这里相当危险,因为这是不受信任的输入。您可以使用正则表达式获取字典名称和密钥名称,并使用vars
和dict.get
进行查找。
import re
a = {'b': {'c': True}}
in_ = 'a.b.c'
match = re.match(
r"""(?P<dict> # begin named group 'dict'
[^.]+ # one or more non-period characters
) # end named group 'dict'
\. # a literal dot
(?P<keys> # begin named group 'keys'
.* # the rest of the string!
) # end named group 'keys'""",
in_,
flags=re.X)
d = vars()[match.group('dict')]
for key in match.group('keys'):
d = d.get(key, None)
if d is None:
# handle the case where the dict doesn't have that (sub)key!
print("Uh oh!")
break
result = d
# result == True
甚至更简单:分裂点。
in_ = 'a.b.c'
input_split = in_.split('.')
d_name, keys = input_split[0], input_split[1:]
d = vars()[d_name]
for key in keys:
d = d.get(key, None)
if d is None:
# same as above
result = d
答案 1 :(得分:2)
s = "a.b.c"
s = s.replace(".", "][")+"]" # 'a][b][c]'
i = s.find("]") # find the first "]"
s = s[:i]+s[i+1:] # remove it 'a[b][c]'
s = s.replace("]", "\"]").replace("[", "[\"") # add quotations 'a["b"]["c"]'
# you can now execute it:
v = eval(s)
答案 2 :(得分:1)
我遇到了同样的问题,在不同的部分解析带有点分隔键的ini文件。 e.g:
[app]
site1.ftp.host = hostname
site1.ftp.username = username
site1.database.hostname = db_host
; etc..
所以我写了一个小函数来将“add_branch”添加到现有的dict树中:
def add_branch(tree, vector, value):
"""
Given a dict, a vector, and a value, insert the value into the dict
at the tree leaf specified by the vector. Recursive!
Params:
data (dict): The data structure to insert the vector into.
vector (list): A list of values representing the path to the leaf node.
value (object): The object to be inserted at the leaf
Example 1:
tree = {'a': 'apple'}
vector = ['b', 'c', 'd']
value = 'dog'
tree = add_branch(tree, vector, value)
Returns:
tree = { 'a': 'apple', 'b': { 'c': {'d': 'dog'}}}
Example 2:
vector2 = ['b', 'c', 'e']
value2 = 'egg'
tree = add_branch(tree, vector2, value2)
Returns:
tree = { 'a': 'apple', 'b': { 'c': {'d': 'dog', 'e': 'egg'}}}
Returns:
dict: The dict with the value placed at the path specified.
Algorithm:
If we're at the leaf, add it as key/value to the tree
Else: If the subtree doesn't exist, create it.
Recurse with the subtree and the left shifted vector.
Return the tree.
"""
key = vector[0]
tree[key] = value \
if len(vector) == 1 \
else add_branch(tree[key] if key in tree else {},
vector[1:],
value)
return tree
答案 3 :(得分:0)
pyjq库的功能与此非常相似,不同之处在于您必须显式提供一个字典作为根,并且必须在字符串前面加上一个.
来引用任何字典。你的根。
python:
import pyjq
d = { 'a' : { 'b' : { 'c' : 'd' } } }
for path in ['.a', '.a.b', '.b.c.d', '.x']:
print(pyjq.first(path, d))
输出:
{'b': {'c': 'd'}}
{'c': 'd'}
None
None