如何对链接的元组列表进行排序?

时间:2010-06-30 05:32:19

标签: python list sorting tuples topological-sort

lst = [(u'course', u'session'), (u'instructor', u'session'), (u'session', u'trainee'), (u'person', u'trainee'), (u'person', u'instructor'), (u'course', u'instructor')]

我上面是元组列表,我需要按照以下逻辑对其进行排序.... 每个元组的第二个元素依赖于第一个元素,例如(课程,课程) - >会话取决于课程等等。

我想要一个基于其依赖关系的优先级的排序列表,较少或独立的对象将首先出现,因此输出应如下所示,

lst = [course, person, instructor, session, trainee]

2 个答案:

答案 0 :(得分:5)

您正在寻找所谓的topological sort。维基百科页面显示了经典的Kahn和深度优先搜索算法; Python示例here(有点过时了,但仍然可以运行正常),pypi(稳定且可重复使用 - 您还可以在线阅读代码here)和{{3} (Tarjan的算法,那种也处理指定的依赖项中的循环),仅举几例。

答案 1 :(得分:4)

从概念上讲,您需要做的是创建一个directed acyclic graph,其边缘由列表内容决定,然后在图表上执行topological sort。在Python的标准库中不存在执行此操作的算法(至少,我不能想到这一点),但您可以在线找到大量第三方实现,例如http://www.bitformation.com/art/python_toposort.html

该网站的功能会获取所有字符串items的列表,以及字符串partial_order之间的另一对列表。您的lst应作为第二个参数传递。要生成第一个参数,可以使用itertools.chain.from_iterable(lst),因此整个函数调用将是

import itertools
lst = ...
ordering = topological_sort(itertools.chain.from_iterable(lst), lst)

或者您可以从网站修改该功能,只使用一个参数,并直接根据lst中的值创建图表中的节点。

编辑:使用Alex Martelli关联的topsort模块,您可以直接传递lst