【发布时间】:2019-01-06 04:22:51
【问题描述】:
如果我使用记忆装饰器,我的 Python 寻路函数会返回不同的结果。它自己返回一个正确的值,但被记忆后,它返回一个错误的值。
我说的函数是这样的:
@functools.lru_cache(maxsize=None)
def recursiveTraversal(originIndex, target, steps):
startingVertex = data[originIndex]
if startingVertex["ID"] == target:
if steps == 0:
return Path(0, [])
else:
return None
else:
if steps == 0:
return None
else:
potentialPaths = []
for i in startingVertex["Edges"]:
nextVertex = data[i]
nextPath = recursiveTraversal(i, target, steps - 1)
if nextPath == None:
continue
nextPath.weight += int(nextVertex["Weight"])
nextPath.vertices.append(i)
potentialPaths.append(nextPath)
if len(potentialPaths) > 0:
minPath = min(potentialPaths, key=lambda x: x.weight)
return minPath
else:
return None
一个完整的可运行示例can be found here。文件的上半部分是所有数据,代码在下。要重现这一点,只需注释掉第 15 行,并观察输出是否不同。
如何让memoized版本输出和普通版本一样的东西?
【问题讨论】:
-
输入在哪里?
-
你能给我们一个minimal reproducible example吗?首先,该输入应该是问题的一部分,而不是评论。更重要的是,如果你只是在我们给定的代码上运行
recursiveTraversal(0, "1", 3),显然只会在data上引发NameError。 -
另外,你说这里的数据根本没有改变……但那些
nextPath值不只是引用data中的某个节点吗?一眼看去,我看不到任何地方可以返回其他任何东西。然后您立即通过更改其权重并附加另一个顶点来修改返回的任何内容。 -
nextVertex是对data的引用,但我实际上是在更改nextPath,它是一个Path 对象,而不是对data的引用。 -
我刚刚用一个可运行的示例更新了这个(包含
data和Path类)。
标签: python recursion optimization path-finding memoization