我想解决如果我的问题是可以解决使用内置排序()函数,或者如果我需要自己做 - 使用cmp的老学校本来会相对容易。Python:排序依赖列表
我的数据集看起来像:
x = [ ('business', Set('fleet','address')) ('device', Set('business','model','status','pack')) ('txn', Set('device','business','operator')) ....
排序规则应基本对于N & Y,其中Y> N,X [N] [0]不是在X [Y] [所有值1]
尽管我使用Python 2.6,其中cmp参数仍然可用,但我试图让这个Python 3安全。
那么,这可以使用一些lambda魔术和关键参数来完成?
- == UPDATE == -
感谢礼&温斯顿!我真的不认为使用钥匙会起作用,或者如果我能怀疑它会是一种不理想的鞋子喇叭解决方案。
因为我的问题是数据库表依赖关系,我不得不对Eli的代码做一个小的添加,以便从它的依赖列表中删除一个项目(在设计良好的数据库中,这不会发生,但是谁住在那个神奇的完美世界)
我的解决方案:
def topological_sort(source):
"""perform topo sort on elements.
:arg source: list of ``(name, set(names of dependancies))`` pairs
:returns: list of names, with dependancies listed first
"""
pending = [(name, set(deps)) for name, deps in source]
emitted = []
while pending:
next_pending = []
next_emitted = []
for entry in pending:
name, deps = entry
deps.difference_update(set((name,)), emitted) # <-- pop self from dep, req Py2.6
if deps:
next_pending.append(entry)
else:
yield name
emitted.append(name) # <-- not required, but preserves original order
next_emitted.append(name)
if not next_emitted:
raise ValueError("cyclic dependancy detected: %s %r" % (name, (next_pending,)))
pending = next_pending
emitted = next_emitted
什么是'Set'? – 2012-07-19 08:56:56
http://en.wikipedia.org/wiki/Topological_sorting – interjay 2012-07-19 09:05:14
@JonClements我会假设他的意思是'sets.Set',尽管在他说他使用的Python 2.6中已经废弃了。但是,如果这就是他的意思,那么他需要向构造函数提供一个迭代器,而不是多个参数。 – Duncan 2012-07-19 12:50:32