需要转x:
X = [['A', 'B', 'C'], ['A', 'B', 'D']]
进入Y:
Y = {'A': {'B': {'C','D'}}}
更具体地说,我需要从绝对路径列表中创建一个文件夹和文件树,如下所示:
paths = ['xyz/123/file.txt', 'abc/456/otherfile.txt']
其中,每个路径都是split("/")
,如伪示例中的['A', 'B', 'C']
所示。
由于这代表文件和文件夹,显然,在同一级别(数组的索引)上,相同的名称字符串不能重复。
答案 0 :(得分:24)
X = [['A', 'B', 'C'], ['A', 'B', 'D'],['W','X'],['W','Y','Z']]
d = {}
for path in X:
current_level = d
for part in path:
if part not in current_level:
current_level[part] = {}
current_level = current_level[part]
这使我们d包含{'A': {'B': {'C': {}, 'D': {}}}, 'W': {'Y': {'Z': {}}, 'X': {}}}
。任何包含空字典的项目都是文件或空目录。
答案 1 :(得分:6)
假设{'C', 'D'}
表示set(['C', 'D'])
且您的Python版本支持dict comprehension
和set comprehension
,这是一个丑陋却又有效的解决方案:
>>> tr = [[1, 2, 3], [1, 2, 4], [5, 6, 7]]
>>> {a[0]: {b[1]: {c[2] for c in [y for y in tr if y[1] == b[1]]} for b in [x for x in tr if x[0] == a[0]]} for a in tr}
{1: {2: set([3, 4])}, 5: {6: set([7])}}
至于你的例子:
>>> X = [['A', 'B', 'C'], ['A', 'B', 'D']]
>>> {a[0]: {b[1]: {c[2] for c in [y for y in X if y[1] == b[1]]} for b in [x for x in X if x[0] == a[0]]} for a in X}
{'A': {'B': set(['C', 'D'])}}
但请不要在实际应用中使用它:)
更新:这是一个适用于任意深度的工具:
>>> def todict(lst, d=0):
... print lst, d
... if d > len(lst):
... return {}
... return {a[d]: todict([x for x in X if x[d] == a[d]], d+1) for a in lst}
...
>>> todict(X)
{'A': {'B': {'C': {}, 'D': {}}}}
答案 2 :(得分:1)
这应该非常接近你所需要的:
def path_to_dict(path):
parts = path.split('/')
def pack(parts):
if len(parts) == 1:
return parts
elif len(parts):
return {parts[0]: pack(parts[1:])}
return parts
return pack(parts)
if __name__ == '__main__':
paths = ['xyz/123/file.txt', 'abc/456/otherfile.txt']
for path in paths:
print '%s -> %s' % (path, path_to_dict(path))
结果:
xyz/123/file.txt -> {'xyz': {'123': ['file.txt']}}
abc/456/otherfile.txt -> {'abc': {'456': ['otherfile.txt']}}
答案 3 :(得分:0)
您的问题陈述中存在逻辑上的不一致。如果你真的想要
['xyz/123/file.txt', 'abc/456/otherfile.txt']
要改为
{'xyz': {'123': 'file.txt}, 'abc': {'456': 'otherfile.txt'}}
然后你必须回答如何将没有前导文件夹的路径'abc.txt'插入到这个数据结构中。顶级字典键是否为空字符串''
?
答案 4 :(得分:0)
我在 twitter 上被问到这个问题,并使用函数式编程想出了这个巧妙的解决方案,我想我不妨在这里分享一下。
from functools import reduce
X = [['A', 'B', 'C'], ['A', 'B', 'D']]
Y = [reduce(lambda x, y: {y:x}, Y[::-1]) for Y in X]
返回:
[{'A': {'B': 'C'}}, {'A': {'B': 'D'}}]
根据需要。
对于更简单的问题,您有一个列表要表示为带有嵌套键的 dict,这就足够了:
from functools import reduce
X = ['A', 'B', 'C']
reduce(lambda x, y: {y:x}, X[::-1])
返回:
{'A': {'B': 'C'}}