[英]how can I create nested dictionary keys and assign them values from a list of namespaced key value pairs?
I have env vars that looks like this:我有看起来像这样的环境变量:
CONFIG-SOMEKEY-SOMEOTHERKEY = val345
CONFIG-SOMEKEY-SOMEOTHEROTHERKEY = val678
CONFIG-ANOTHERKEY = val222
I want to create a dictionary out of them that would look like:我想用它们创建一个字典,看起来像:
{
'SOMEKEY': {
'SOMEOTHERKEY': 'val3242',
'SOMEOTHEROTHERKEY': 'val678'
}
'ANOTHERKEY': 'val222'
}
"CONFIG-" is a prefix to denote which vars this should be done with- so I can filter them easily like this: “CONFIG-”是一个前缀,表示应该使用哪些变量——所以我可以像这样轻松过滤它们:
config_fields = [i for i in os.environ if i.startswith("CONFIG-")]
But I'm unsure of how to loop over the string, split on "-" and build a dict.但我不确定如何遍历字符串,在“-”上拆分并构建一个字典。
While looping I was thinking I could check if its the last item and assign the value but how would it know the full path of keys it's on?循环时我在想我可以检查它是否是最后一项并分配值,但是它如何知道它所在键的完整路径?
I suspect this is a job for recursion I'm just now sure exactly how to implement it我怀疑这是递归的工作我现在才确定如何实现它
You can use the assoc_in
function from toolz .您可以使用来自 toolz 的
assoc_in
function 。 Split the name on -
and slice off the prefix.拆分名称
-
并切掉前缀。
import os
from toolz.dictoolz import assoc_in
CONFIG={}
for k, v in os.environ.items():
if k.startswith("CONFIG-"):
assoc_in(CONFIG, k.split('-')[1:], v)
If you don't want to add a dependency, you can see the implementation of assoc_in
here .如果您不想添加依赖项,可以在此处查看
assoc_in
的实现。 A simpler substitute might be something like一个更简单的替代品可能是
def assoc_in(d, ks, v):
for k in ks[:-1]:
d = d.setdefault(k, {})
d[ks[-1]] = v
This uses the .setdefault()
method to get the nested dicts, which will add a new one if it doesn't exist yet.这使用
.setdefault()
方法来获取嵌套的 dicts,如果它还不存在,它将添加一个新的。
You could do:你可以这样做:
data = ['CONFIG-SOMEKEY-SOMEOTHERKEY = val345',
'CONFIG-SOMEKEY-SOMEOTHEROTHERKEY = val678',
'CONFIG-ANOTHERKEY = val222']
result = {}
for e in data:
key, value = e.split(" = ") # split into key and value
path = key.split("-") # split the key into parts
ref = result
for part in path[1:-1]:
ref[part] = part in ref and ref[part] or {}
ref = ref[part]
ref[path[-1]] = value # take the last part of key and set the value
print(result)
Output Output
{'SOMEKEY': {'SOMEOTHERKEY': 'val345', 'SOMEOTHEROTHERKEY': 'val678'}, 'ANOTHERKEY': 'val222'}
This part:这部分:
ref = result
for part in path[1:-1]:
ref[part] = part in ref and ref[part] or {}
ref = ref[part]
ref[path[-1]] = value
will create the nested dictionaries, is equivalent to:将创建嵌套字典,相当于:
for part in path[1:-1]:
if part not in ref:
ref[part] = {}
ref = ref[part]
So if the part
is in the dictionary you set ref as the value corresponding to part
otherwise you create a new dictionary.因此,如果
part
在字典中,则将 ref 设置为与part
相对应的值,否则将创建一个新字典。
You can get your environment variables like so:您可以像这样获取环境变量:
import os
text = [f"{k} = {v}" for k,v in os.environ.items() if k.startswith("CONFIG-")]
print(env)
(inspired by How to access environment variable values? - especially this answer ) (灵感来自如何访问环境变量值? -尤其是这个答案)
Then you can use dicts to iterativly splitting your values:然后,您可以使用 dicts 迭代拆分您的值:
text = """CONFIG-SOMEKEY-SOMEOTHERKEY = val345
CONFIG-SOMEKEY-SOMEOTHEROTHERKEY = val678
CONFIG-ANOTHERKEY = val222"""
text = text.split("\n")
d = {}
curr_d = d
for part in text:
while "-" in part:
a, b = part.split("-",1)
if '-' in b:
curr_d [a] = curr_d.get(a,{})
curr_d = curr_d[a]
part = b
a, b = part.split("=",1)
curr_d[a] = b
curr_d = d
print(d)
Output: Output:
{'CONFIG': {'SOMEOTHERKEY ': ' val345',
'SOMEOTHEROTHERKEY ': ' val678'},
'ANOTHERKEY ': ' val222'}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.