【问题标题】:sorting python list based on "dependencies" from dictionary根据字典中的“依赖项”对python列表进行排序
【发布时间】:2021-06-06 15:48:24
【问题描述】:

假设我有以下列表foo 想要排序:

foo = [63,64,65]

为了通知排序,我有以下“依赖项”字典,如果 valuekey 的列表中,则该 value 的排序必须高于列表foo 中的key

bar = {
    63: [64, 65],
    64: [65]
}

例如,查看列表foo,我们在索引0 处看到值63。但是,检查字典bar,我们看到63 具有“依赖关系”6465,因此这两个值在foo 中的排序必须更高。

我相信我可以拼凑出一些东西,但我对解决这种排序场景的算法和/或其他方法很感兴趣。谢谢。

更新: 许多 cmets 指出这可能是图形/拓扑问题。谢谢你,因为这实际上是对图中的节点进行排序的更大任务的一部分。

更新: 建议查看toposort,这正好符合要求。

【问题讨论】:

  • 这听起来确实像一个图形问题
  • 这听起来像是拓扑排序 - 你研究过吗?
  • 另见pypi.org/project/toposort,一个为你处理拓扑排序的现成项目。
  • 请注意,从技术上讲,64 不是键 63 的值。 包含 64 的列表是键 63 的值。

标签: python sorting


【解决方案1】:

所以,把所有的 cmets 放在一起:

您的情况对应于一个有向图,其中每条边都是一个依赖项。对有向(非循环)图或短 DAG 进行排序的正确方法称为 topological sorting

在 Python 中已经有一个包可以做到这一点,toposort。 但是,它要求您的值是集合,而不是列表,但这很容易解决:

from toposort import toposort_flatten

bar = {
    63: [64, 65],
    64: [65]
}

graph = dict(zip(bar.keys(), map(set, bar.values())))
sorted_graph = toposort_flatten(graph, sort=True)

因为听起来您的图表可能包含不在foo 中的条目,您可以像这样对foo 进行排序:

foo = [63,64,65]
foo_set = set(foo)
foo_sorted = [x for x in sorted_graph if x in foo_set]
print(foo_sorted)
# [65, 64, 63]

或者,如果图表比您要排序的列表大很多(并且迭代它需要很多时间),请构建一个字典:

graph_sorted_lookup = {x: i for i, x in enumerate(sorted_graph)}
foo_sorted = sorted(foo, key=graph_sorted_lookup.get)

【讨论】:

  • 这种方法很完美,正如 cmets 中建议的库拓扑排序一样。
  • @MartijnPieters:这总是可能的吗?如果图表是a -> b, c -> d -> b,并且您想对列表[a, b, c] 进行排序,则即使d 不在列表中,您也不能从图表中删除它,因为否则c 可以在a 和@ 之前排序987654334@.
猜你喜欢
  • 2023-03-26
  • 1970-01-01
  • 2014-03-13
  • 2015-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多