我的env var看起来像这样:
CONFIG-SOMEKEY-SOMEOTHERKEY = val345
CONFIG-SOMEKEY-SOMEOTHEROTHERKEY = val678
CONFIG-ANOTHERKEY = val222
我想用它们创建一个字典,像这样:
{
'SOMEKEY': {
'SOMEOTHERKEY': 'val3242',
'SOMEOTHEROTHERKEY': 'val678'
}
'ANOTHERKEY': 'val222'
}
“ CONFIG-”是一个前缀,表示应该使用哪个变量-所以我可以像这样轻松过滤它们:
config_fields = [i for i in os.environ if i.startswith("CONFIG-")]
但是我不确定如何遍历字符串,分割为“-”并构建字典。
在循环时,我在想可以检查它是否为最后一项并分配值,但是它怎么知道它所在键的完整路径?
我怀疑这是递归工作,我现在才确定确切地实现它
答案 0 :(得分:2)
您可以使用toolz中的assoc_in
功能。在-
上拆分名称,然后切掉前缀。
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)
如果您不想添加依赖项,则可以看到assoc_in
here的实现。一个更简单的替代方法可能是
def assoc_in(d, ks, v):
for k in ks[:-1]:
d = d.setdefault(k, {})
d[ks[-1]] = v
这使用.setdefault()
方法获取嵌套的字典,如果尚不存在,则会添加一个新字典。
答案 1 :(得分:2)
您可以这样做:
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)
输出
{'SOMEKEY': {'SOMEOTHERKEY': 'val345', 'SOMEOTHEROTHERKEY': 'val678'}, 'ANOTHERKEY': 'val222'}
此部分:
ref = result
for part in path[1:-1]:
ref[part] = part in ref and ref[part] or {}
ref = ref[part]
ref[path[-1]] = value
将创建嵌套字典,等效于:
for part in path[1:-1]:
if part not in ref:
ref[part] = {}
ref = ref[part]
因此,如果part
在字典中,则将ref设置为与part
对应的值,否则创建一个新字典。
答案 2 :(得分:1)
您可以像这样获取环境变量:
import os
text = [f"{k} = {v}" for k,v in os.environ.items() if k.startswith("CONFIG-")]
print(env)
(受How to access environment variable values?的启发-尤其是answer的灵感)
然后,您可以使用dict迭代拆分值:
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)
输出:
{'CONFIG': {'SOMEOTHERKEY ': ' val345',
'SOMEOTHEROTHERKEY ': ' val678'},
'ANOTHERKEY ': ' val222'}