比较Python中文件树的路径

比较Python中文件树的路径,python,tree,iteration,yaml,traversal,Python,Tree,Iteration,Yaml,Traversal,我有一个带有文件夹树的YAML文件,如下所示: --- - folder1 - folder2: - subfolder1: - deepfolder1 - subolder2 - folder3 - folder4 ... 我打开它: with open(yaml_file) as f: tree = yaml.load(f) 我想将它与URL路径进行比较 然后我拆分URL元素以获得一个列表[folder1,folder2] 请求路径应该是指

我有一个带有文件夹树的YAML文件,如下所示:

---
- folder1
- folder2:
    - subfolder1:
        - deepfolder1
    - subolder2
- folder3
- folder4
...
我打开它:

with open(yaml_file) as f:
        tree = yaml.load(f)
我想将它与URL路径进行比较

然后我拆分URL元素以获得一个列表[folder1,folder2]

请求路径应该是指向文件夹的相对链接,不带尾随斜杠

我想检查请求路径是否位于YAML文件夹树中,然后返回例如True

但是,我有点迷茫,不知道如何以一种有序的、python式的方式来比较这两个对象

我想到的所有东西都有很多圈,感觉非常臃肿,既不时髦也不时髦

我使用的是Python3.4,我对Python基本上是新手


如果有更好的方法在YAML文件的其他结构中进行比较,或者有不同的方法来比较这些,那么欢迎您的每一个建议

您可能需要进一步解释如何比较这两个对象,但我想您的主要问题是希望将嵌套目录结构转换为路径的平面列表。也就是说,您想要这个嵌套结构:

- folder2:
    - subfolder1:
        - deepfolder1
        - deepfolder2
要成为这些内容的简单列表,请执行以下操作:

folder2/subfolder1/deepfolder1
folder2/subfolder1/deepfolder2
这是一种形式

这里一个棘手的部分是,通常树表示为列表列表,但YAML混合了关联数组,即dict或hash和列表。所以这使得代码更复杂一些

下面是对给定数据的递归树遍历:

def traverse(t, prefix=None):
    prefix = prefix or []

    if len(t) == 0:
        raise StopIteration
    elif len(t) == 1:
        first, rest = t[0], []
    else:
        first, rest = t[0], t[1:]

    #walk first element
    if isinstance(first, str):
        #it's a single node
        yield prefix + [first]
    elif isinstance(first, list):
        #it's a list of nodes
        for element in first:
            for tmp in traverse(element, prefix=prefix):
                yield tmp
    elif isinstance(first, dict):
        #there's another level of nesting
        for sub in first:
            for tmp in traverse(first[sub], prefix=(prefix + [sub])):
                yield tmp

    #walk rest of elements recursively
    for element in traverse(rest, prefix=prefix):
        yield element

for expanded_path in traverse(tree):
    print(expanded_path)
如果您使用的是Python3.4,那么可以使用yield from来清理…:yield tmp parts.中的for tmp

当我对您的数据执行此操作时,我得到:

['folder1']
['folder2', 'subfolder1', 'deepfolder1']
['folder2', 'subolder2']
['folder3']
['folder4']
这些扩展路径与path_elements变量的格式相同,因此我们现在可以将它们相互比较

您可能想要或者为了更好的树遍历算法,我的可能不是最有效的,所以您可能需要在生产中使用迭代版本

编辑:响应您的注释:返回“True”如果请求路径在树结构中,您只需在扩展路径上循环,查看请求路径是否与其中任何路径匹配:

def compare(request_path, tree):
    path_elements = parse.unquote_plus(request_path).split(sep)
    for expanded_path in traverse(tree):
        if expanded_path == path_elements:
            return True
    return False

但这在某种程度上取决于请求路径中的内容,它是完整URL还是绝对URL/foo/boo.txt还是相对URL foo/boo.txt?如果是这样,您可能需要在比较路径之前清理路径。虽然搜索拆分路径和URL非常容易,但在树上行走是非常复杂的部分。

谢谢!我为这个问题添加了一个更具体的目标:如果请求路径在树结构中,则返回“True”。一旦有了扩展路径列表,这一部分就很容易了。只需在所有扩展路径上循环,并将每个路径与请求路径进行比较。我用这些信息编辑了我的答案。
def compare(request_path, tree):
    path_elements = parse.unquote_plus(request_path).split(sep)
    for expanded_path in traverse(tree):
        if expanded_path == path_elements:
            return True
    return False