您可能需要多解释一下您希望如何“比较”这两个对象,但我猜您的主要问题是您想将嵌套目录结构转换为平面列表的路径。 IE。你想要这个嵌套结构:
- folder2:
- subfolder1:
- deepfolder1
- deepfolder2
要成为这些的平面列表:
folder2/subfolder1/deepfolder1
folder2/subfolder1/deepfolder2
这是“tree traversal”的一种形式。
这里有一个棘手的部分是,通常树表示为列表的列表,但您的 YAML 混合了关联数组(AKA 字典或哈希)和列表。所以这会让代码稍微复杂一些。
以下是您提供的数据的递归树遍历:
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)
如果您使用的是 python 3.4,则可以使用 yield from 清理“for tmp in ...: yield tmp”部分。 Full code here.
当我在你的数据上运行时,我得到:
['folder1']
['folder2', 'subfolder1', 'deepfolder1']
['folder2', 'subolder2']
['folder3']
['folder4']
这些扩展路径的格式与您的 path_elements 变量的格式相同,因此我们现在可以将它们相互比较。
您可能想要search SO 或python recipes 以获得更好的树遍历算法,我的可能不是最有效的(有一个limit to python's recursion depth,因此您可能需要在生产中使用迭代版本)。
编辑:针对您的评论:“如果 request_path 在树结构内,则返回 'True'”,您只需遍历扩展路径并查看 request_path 是否与其中任何一个匹配:
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
但这在一定程度上取决于 request_path 中的内容,它是完整 URL (http://www.blah.com/foo/boo.txt) 还是绝对 URL (/foo/boo.txt) 还是相对 URL (foo/boo.txt)?如果是这样,您可能需要在比较它们之前清理路径。不过,这一切都很容易做到(搜索 SO 来分割路径和 URL),遍历树是复杂的部分。