Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 提取嵌套目录和列表中找到的叶值集,不包括None_Python_Recursion_Nested_Flatten - Fatal编程技术网

Python 提取嵌套目录和列表中找到的叶值集,不包括None

Python 提取嵌套目录和列表中找到的叶值集,不包括None,python,recursion,nested,flatten,Python,Recursion,Nested,Flatten,我有一个从YAML读取的嵌套结构,它由嵌套列表和/或嵌套DICT组成,或者在不同的嵌套级别上由这两者混合而成。可以假设该结构不包含任何递归对象 如何仅从中提取叶值?另外,我不想要任何None值。叶值包含我所关心的字符串。考虑到结构的最大深度不足以超过堆栈递归限制,可以使用递归。发电机也可以选择 存在着类似的问题,涉及到扁平化列表或口述,但不是两者的混合。或者,如果展平dict,它们也会返回我并不真正需要的展平键,并冒名称冲突的风险 我试过了,但它的示例仅显示它可以处理嵌套列表,而不能处理dict

我有一个从YAML读取的嵌套结构,它由嵌套列表和/或嵌套DICT组成,或者在不同的嵌套级别上由这两者混合而成。可以假设该结构不包含任何递归对象

如何仅从中提取叶值?另外,我不想要任何
None
值。叶值包含我所关心的字符串。考虑到结构的最大深度不足以超过堆栈递归限制,可以使用递归。发电机也可以选择

存在着类似的问题,涉及到扁平化列表或口述,但不是两者的混合。或者,如果展平dict,它们也会返回我并不真正需要的展平键,并冒名称冲突的风险

我试过了,但它的示例仅显示它可以处理嵌套列表,而不能处理dicts和list的混合

样本输入
struct1={
“k0”:无,
“k1”:“v1”,
“k2”:[“v0”,无,“v1”],
“k3”:[“v0”、[“v1”、“v2”、无、[“v3”]、[“v4”、“v5”]、[],
“k4”:{“k0”:无},
“k5”:{“k1”:{“k2”:{“k3”:“v3”,“k4”:“v6”},“k4”:{}},
“k6”:[{},{“k1”:“v7”},{“k2”:“v8”,“k3”:“v9”,“k4”:{“k5”:{“k6”:“v10”},k7”:{},
“k7”:{
“k0”:[],
“k1”:[“v11”],
“k2”:[“v12”、“v13”],
“k3”:[“v14”、[“v15”],
“k4”:[“v16”],[“v17”],
“k5”:[“v18”、[“v19”、“v20”、[“v21”、“v22”、[]],
},
}
结构2=[“aa”,“bb”,“cc”,“dd”,“ee”,“ff”,“gg”,无,[]]
预期产出
struct1_leaves={f“v{i}”表示范围(23)内的i
struct2_leaves={f{s}{s}表示“abcdefg”中的s

这是一个简单的参考解决方案,它使用递归为问题中包含的示例输入生成预期输出

从键入import Any开始,设置
def leaves(struct:Any)->Set[Any]:
“”“返回嵌套目录和列表中的一组叶值,不包括无值。”“”
#参考:https://stackoverflow.com/a/59832362/
值=集合()
如果isinstance(结构、目录):
对于struct.values()中的子结构:
值。更新(叶(子结构))
elif isinstance(结构,列表):
对于结构中的子结构:
值。更新(叶(子结构))
elif结构不是无:
values.add(结构)
返回值

另一种可能性是使用带递归的生成器:

struct1 = {'k0': None, 'k1': 'v1', 'k2': ['v0', None, 'v1'], 'k3': ['v0', ['v1', 'v2', None, ['v3'], ['v4', 'v5'], []]], 'k4': {'k0': None}, 'k5': {'k1': {'k2': {'k3': 'v3', 'k4': 'v6'}, 'k4': {}}}, 'k6': [{}, {'k1': 'v7'}, {'k2': 'v8', 'k3': 'v9', 'k4': {'k5': {'k6': 'v10'}, 'k7': {}}}], 'k7': {'k0': [], 'k1': ['v11'], 'k2': ['v12', 'v13'], 'k3': ['v14', ['v15']], 'k4': [['v16'], ['v17']], 'k5': ['v18', ['v19', 'v20', ['v21', 'v22', []]]]}}
def flatten(d):
   for i in getattr(d, 'values', lambda :d)():
      if isinstance(i, str):
         yield i
      elif i is not None:
         yield from flatten(i)

print(set(flatten(struct1)))
输出:

{'v10', 'v9', 'v8', 'v7', 'v0', 'v18', 'v16', 'v1', 'v21', 'v11', 'v14', 'v15', 'v12', 'v13', 'v4', 'v2', 'v5', 'v20', 'v6', 'v19', 'v3', 'v22', 'v17'}
{'cc', 'ff', 'dd', 'gg', 'bb', 'ee', 'aa'}

输出:

{'v10', 'v9', 'v8', 'v7', 'v0', 'v18', 'v16', 'v1', 'v21', 'v11', 'v14', 'v15', 'v12', 'v13', 'v4', 'v2', 'v5', 'v20', 'v6', 'v19', 'v3', 'v22', 'v17'}
{'cc', 'ff', 'dd', 'gg', 'bb', 'ee', 'aa'}

这是对的自适应,以使用内部函数和单个
集。它还使用递归为问题中包含的样本输入生成预期输出。它避免了通过整个调用堆栈传递每个叶

从键入import Any开始,设置
def leaves(struct:Any)->Set[Any]:
“”“返回嵌套目录和列表中的一组叶值,不包括无值。”“”
#参考:https://stackoverflow.com/a/59832594/
值=集合()
def add_leaves(结构:任意)->无:
如果是实例(结构,dict):
对于结构值()中的子结构:
添加叶子(子结构)
elif isinstance(结构,列表):
对于结构中的子结构:
添加叶子(子结构)
elif结构不是无:
值。添加(结构)
添加叶子(结构)
返回值


信用:通过

的建议似乎没有效率,将每个叶通过整个调用堆栈,一遍又一遍地更新到集合中。你可以有一个递归的内部函数,它不返回任何内容,而是将所有内容添加到外部函数所持有的集合中(非递归,只调用内部)。@HeapOverflow添加了建议。谢谢你的主意。