使用字典中的特定键构建列表(python)?
我正在用 Python 实现 Dijkstra 搜索算法。在搜索结束时,我使用前驱图重建最短路径,从目标节点的前驱开始。例如:
path = []
path.append(destination)
previous = predecessor_map[destination]
while previous != origin:
path.append(previous)
previous = predecessor_map[previous]
有什么方法可以用更少的代码行来做到这一点(例如列表理解)?
I'm implementing the Dijkstra search algorithm in Python. At the end of the search, I reconstruct the shortest path using a predecessor map, starting with the destination node's predecessor. For example:
path = []
path.append(destination)
previous = predecessor_map[destination]
while previous != origin:
path.append(previous)
previous = predecessor_map[previous]
Is there any way to do this with less lines of code (e.g. list comprehension)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我唯一的建议是消除轻微的代码重复:
除此之外,我认为您的代码实际上非常清晰,并且不太可能从任何缩短代码的尝试中受益。
最后,值得注意的是,当
destination == origin
时,上述内容也适用,而您的原始版本很可能不会(取决于predecessor_map
的填充方式)。不知道这是否与您的用例相关。The only suggestion that I have is to get rid of the slight code duplication:
Beyond that, I think your code is actually very clear and is unlikely to benefit from any attempts to shorten it.
Lastly, it is worth noting that the above also works when
destination == origin
, whereas your original version most probably doesn't (depends on how exactlypredecessor_map
is populated). Don't know if this is relevant to your use cases.这可能有效:
它的行为与您的原始代码相同。但你已经写的就很好了。
如果
destination
可以等于origin
:它的行为与@aix 的代码。
This might work:
It behaves the same as your original code. But what you've already written is fine as is.
If
destination
could be equal toorigin
:It behaves the same as @aix's code.
这将步行和收集任务分开。
如果你能确保你永远不会从原点开始,你可以简化为
This separates the walking and collecting tasks.
If you can ensure that you never start with the origin, you can simplify to
您可以递归地遍历边,假设
predecessor_map
是一个dict
将节点映射到父节点,并且None
是根:定义一个遍历的递归函数反向树:
或者,如果你敢的话,Y 组合器:
使用中(使用列表理解):
You can recursively traverse the edges assuming
predecessor_map
is adict
mapping node to parent node and thatNone
is the root:Define a recursive function that traverses the tree in reverse:
Or, if you dare, a Y combinator:
In use (using list comprehension):
另一种可能的解决方案是使用带有延迟输出的函数式编程:
我个人不会使用这种方法。但对于训练来说这很有趣。
说明
关键元素是
deferred_output
,它推迟对output
的调用。然后我们使用
tee
将output
拆分为 2 个迭代器。然后,我们将
predecessor_map.get
应用于名为a
的第二个迭代器,并将新迭代器分配给b
。然后我们用
takewhile
控制输出,并在到达origin
时停止。One more possible solution is to use functional style programming with deferred output:
I personally wouldn't use this approach. But it's interesting for training though.
Explanation
The key element is
deferred_output
which postpones the calls tooutput
.Then we split
output
into 2 iterators usingtee
.Then we apply
predecessor_map.get
to the second iterator calleda
and assign the new iterator tob
.Then we control the output with
takewhile
and stop whenorigin
is reached.我认为你无法通过理解来完成这次迭代。也许你可以稍微简化一下,就像这样:
上面的循环使用 do..while 看起来会更好,但 Python 缺少它
I don't think you can do this iteration with a comprehension. Maybe you could simplify it a little, like this:
The above loop would look nicer with a do..while , but Python lacks it