为什么Python遍历字典的node函数总返回NoneType且counter被重置
问题原因排查
- 递归返回链路断裂
你只在calls == max_depth的分支里写了return Summe_Knoten,其余所有分支(包括递归调用node(yes_answer)、node(no_answer)的位置)都没有把递归的返回值向上传递,Python函数没有显式写return时默认返回None,这是你拿到NoneType对象的核心原因。 - 返回触发条件太窄
只有当函数调用次数刚好等于max_depth时才会触发返回逻辑,如果你的字典树实际深度小于max_depth,永远不会走到返回分支,自然返回None。 - 可变默认参数有隐患
你用List = []作为默认参数,Python的函数默认参数是在定义阶段初始化的,后续多次调用函数都会复用同一个列表对象,不会每次调用都清空,会导致计数结果异常。 - 函数属性全局污染
你用getattr(node, "calls", 0)来记录调用次数,calls是绑定在函数对象上的全局属性,多次调用函数时不会自动重置,会导致计数逻辑混乱。
修复方案
首先把可变默认参数改为None在函数内部初始化,补全所有递归链路的返回值,调整返回逻辑为遍历完所有节点或者达到最大深度时直接返回求和结果:
def node(tree, max_depth=5, List=None, calls=0, counter=0): # 初始化存储列表,避免可变默认参数问题 if List is None: List = [] print('Calls:', calls) # 递归终止条件:深度超过max_depth就返回求和结果 if calls >= max_depth: Summe_Knoten = sum(List) print("Summe Knoten: ", Summe_Knoten) return Summe_Knoten question = list(tree.keys())[0] yes_answer = tree[question][0] no_answer = tree[question][1] calls += 1 if isinstance(yes_answer, dict) and isinstance(no_answer, dict): # 传递参数,不要用函数属性存储calls res1 = node(yes_answer, max_depth, List, calls, counter) res2 = node(no_answer, max_depth, List, calls, counter) # 向上传递最深层的返回结果 return res2 if res2 is not None else res1 else: if (isinstance(yes_answer, dict) and not isinstance(no_answer, dict)) | (not isinstance(yes_answer, dict) and isinstance(no_answer, dict)): counter += 1 List.append(counter) if isinstance(yes_answer, dict) and not isinstance(no_answer, dict): return node(yes_answer, max_depth, List, calls, counter) if not isinstance(yes_answer, dict) and isinstance(no_answer, dict): return node(no_answer, max_depth, List, calls, counter) else: counter +=2 List.append(counter) # 遍历到叶子节点直接返回求和结果 Summe_Knoten = sum(List) print("Summe Knoten: ", Summe_Knoten) return Summe_Knoten
内容的提问来源于stack exchange,提问作者qoolpoolboy
相关产品推荐
相关产品推荐

