Python将文件系统映射到目录结构:工作,......但是如何?

时间:2014-01-30 11:20:26

标签: python reduce

我正在解析目录。我找到了a snippet here,效果很好,但我似乎无法弄清楚为什么以及如何更新变量dir的位置。

我想做的是遗漏空文件夹

import os

def get_directory_structure(rootdir):
    """
    Creates a nested dictionary that represents the folder structure of rootdir
    """
    dir = {}
    rootdir = rootdir.rstrip(os.sep)
    start = rootdir.rfind(os.sep) + 1
    for path, dirs, files in os.walk(rootdir):
        folders = path[start:].split(os.sep)
        subdir = dict.fromkeys(files)
        parent = reduce(dict.get, folders[:-1], dir)
        parent[folders[-1]] = subdir
    return dir

dir被设置为与父级相同的值:

        parent[folders[-1]] = subdir

为什么?

dir是可变的,并在reduce行中作为输入,但不会在那里设置,而是在下一行。

有什么想法吗?

我希望能够省去空文件夹,而宁愿找到一种优雅的方式来做到这一点;作为第二次通过,我应该放弃并浏览字典吗?

[解密后编辑]所以Hans和Adrin指出,reduce实际上让父指向dir,所以它们是同一个对象,并且父更新的任何更新都是dir。

我最后保留了相同的代码,但为了清晰起见重命名了变量:

dir - > token_dict
folders - > path_as_list
subdir - > files_in_dir
parent - > full_dir(我最终返回full_dir

更多打字,但下次我看,我会立即开始。

2 个答案:

答案 0 :(得分:3)

对于任何不太熟悉的人来说,减少字典的一些解释:

在我们讨论片段之前,让我们做一些减少功能。

Reduce will apply a function of two arguments cumulatively to the items of a sequence, from left to right, so as to reduce the sequence to a single value.

以下是语法:

reduce(function, sequence[, initial]) -> value

如果存在initial,则将其放在计算中序列的项目之前, 当序列为空时用作默认值。

没有首字母:

>>> reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
15
>>>
smiliar to ((((1+2)+3)+4)+5)

初始:

>>> reduce(lambda x, y: x+y, [], 1) 
1
>>>

关于字典,关于字典:

首先让我们检查一下dict.get()方法可以做什么:

>>> d = {'a': {'b': {'c': 'files'}}}
>>> dict.get(d,'a')
{'b': {'c': 'files'}}
>>>

所以,当你把dict.get方法放在reduce中时,会发生这种情况:

>>> d = {'a': {'b': {'c': 'files'}}}
{'b': {'c': 'files'}}
>>> reduce(dict.get, ['a','b','c'], d)
'files'
>>>

类似于:

>>> dict.get(dict.get(dict.get(d,'a'),'b'),'c')
'files'
>>>

当你得到空列表时,你会得到一个空的dict,这是默认值:

>>> reduce(dict.get, [], {})
{}
>>>

让我们回到你的片段:

你的代码段中的dir!= 内置 dir()函数,它只是一个绑定到空字典的名称。

parent = reduce(dict.get, folders[:-1], dir)

因此,在上面的行中,文件夹[: - 1]只是一个目录列表。和dir是empty_dictionary。

如果有任何帮助,请告诉我。

答案 1 :(得分:2)

您正在将dir传递给reduce函数。意思是,你将指向对象的指针传递给函数,函数可以改变它。

查看reduce函数here的实现。请注意以下几行:

accum_value = function(accum_value, x)

此时,accum_value指向与您initializer dir相同的位置,并传递给该函数,在您的情况下为dict.get