假设我们有一个从json解析的dict,并以密钥路径path-to.my.keys
的形式从密钥中读取值
my_dict['path-to']['my']['keys']
在文件系统中,如果mkdir -p
不存在,则它可以创建这样的路径。
在python中,我们是否有类似的语法/函数来为dict创建key path
,也就是为缺少键的默认空dict?我的谷歌搜索结果没有太大帮助。
TLDR
您可以使用dict.setdefault
或collections.defaultdict
。
def make_path(d: dict, *paths: str) -> None:
for key in paths:
d = d.setdefault(key, {})
make_path(my_dict, 'path-to', 'my', 'keys')
assert my_dict['path-to']['my']['keys'] is not None
完整详细信息
解决方案1。dict.setdefault
:
my_dict.setdefault('path-to', {}).setdefault('my', {}).setdefault('keys', {})
优点:
my_dict
为正常dict
- 使dict只显式发生
- 深度无限制
缺点:
- 您应该在每个用例中调用
setdefault
方法
解决方案2。collections.defaultdict
:
from collections import defaultdict
my_dict = defaultdict(lambda: defaultdict(lambda: defaultdict(dict)))
my_dict['path-to']['my']['keys']
优点:
- 您根本不需要调用来检查是否存在
缺点:
- 制作字典是隐含的
- CCD_ 11不是纯CCD_
- 根据
my_dict
的定义,您有深度限制
解决方案3。解决方案1的高级功能:制作自己的功能
def make_path(my_dict: dict, *paths: str) -> dict:
while paths:
key, *paths = paths
my_dict = my_dict.setdefault(key, {})
return my_dict
test = {'path-to': {'test': 1}}
print(test)
make_path(test, 'path-to', 'my', 'keys')['test2'] = 4
print(test)
print(make_path(test)) # It's okay even no paths passed
输出:
{'path-to': {'test': 1}}
{'path-to': {'test': 1, 'my': {'keys': {'test2': 4}}}}
{'path-to': {'test': 1, 'my': {'keys': {'test2': 4}}}}
解决方案4。来自解决方案2的高级:创建自己的类
class MyDefaultDict(dict):
def __missing__(self, key):
self[key] = MyDefaultDict()
return self[key]
my_dict = MyDefaultDict()
print(my_dict)
my_dict['path-to']['my']['keys'] = 'hello'
print(my_dict)
输出:
{}
{'path-to': {'my': {'keys': 'hello'}}}
结论
我认为解决方案3最符合您的需求,但如果适合您的情况,您可以使用任何其他选项。
附加
在解决方案4中,我们已经从json中解析了dict:d,怎么样?您的解决方案从MyDefaultDict((类型开始,而不是从jsons.loads((返回的类型开始
如果您可以编辑json.loads
部分,请尝试:
import json
class MyDefaultDict(dict):
def __missing__(self, key):
self[key] = MyDefaultDict()
return self[key]
data = '{"path-to": {"my": {"keys": "hello"}}}'
my_dict = json.loads(data, object_pairs_hook=MyDefaultDict)
print(type(my_dict))
输出:
<class '__main__.MyDefaultDict'>
有一个递归defaultdict
技巧,允许您在嵌套结构的随机路径上设置值,而无需显式创建路径:
import json
from collections import defaultdict
nested = lambda: defaultdict(nested)
d = nested()
d['path']['to']['nested']['key'] = 'value'
print(json.dumps(d))
# {"path": {"to": {"nested": {"key": "value"}}}}
不存在的键将返回空的defaultdict。
在python中,我们是否有类似的语法/函数来为dict创建密钥路径?我的谷歌搜索结果没有太大帮助。
Python没有clojure&没有。不过,为了方便使用setdefault
方法,它可以在运行时以一定的成本处理这种特定情况:dict.setdefault(key, default)
将在设置键后返回该键的值,如果它丢失,则my_dict.setdefault('path-to', {}).setdefault('my', {}).setdefault('keys', ???)
将访问指定的路径,在它们丢失的地方设置dict。
回答您的问题--是。
在python中,您可以使用subprocess
模块来执行您通常在系统上执行的所有命令。
您可以从python中执行相同的mkdir -p
命令来创建嵌套目录usinfsubprocess.Popen
。
以下是如何做到这一点:
import subprocess
# Create a string of nested directory path.
path_from_dict_keys = "dir1/dir2/dir3"
temp = subprocess.Popen(['mkdir', '-p', path_from_dict_keys], stdout = subprocess.PIPE)
# we use the communicate function to fetch the output
output = str(temp.communicate())