【问题标题】:What's the best way to do this in Python?在 Python 中执行此操作的最佳方法是什么?
【发布时间】:2013-02-10 01:37:03
【问题描述】:

我有一个对象列表,其中每个对象都有 startend 属性,例如:

Item 0:
Start: 1
End: 12

Item 1:
Start: 6
End: 3

Item 2:
Start: 12
End: 6

我想订购它们,以便每个项目的 startend 与新列表中其前后的项目匹配。

所以在这个例子中,它会是:

[Item 0] [Item 2] [Item 1]
[1   12] [12   6] [6    3]

整个列表是否颠倒都没关系。

还有 2 个像上面那样不相关的列表混合在一起,所以我必须形成 2 个新列表,它们的顺序如上所示。

我将开始“蛮力”实施它,因此会进行大量查询来创建这些列表,但我想问是否有人可能有更优雅的方法来解决这个问题。我不确定这类问题有多普遍,但我记得以前见过这个,所以也许有一些模式可以解决这个问题。

【问题讨论】:

    标签: python list sorting collections


    【解决方案1】:

    对元素进行排序表明没有重复项。但是,对于重复的starts 或ends,您必须更加小心(并且可能有多个解决方案)。该问题相当于在无向图的connected components 中找到Eulerian paths,可以通过将每个 (start, end) 对视为图边来获得。

    关于如何在网络上用 Python 实现它的例子已经足够多了。请记住,它可以在 O(m) 时间内轻松完成,其中 m 是边数。

    此外,欧几里得路径存在当且仅当每个顶点都具有偶数度数。如果图表中有很多组件,它仍然成立。

    【讨论】:

    • 谢谢,我的列表没有重复,基本上每个项目都保证有唯一的开始和结束。但我也发现一些起始值和结束值可能会颠倒。
    【解决方案2】:

    假设每个开始和结束都有完美的开始/结束匹配:

    items_by_start = dict((i.start, i) for i in your_items)
    
    ordered_items = [your_items[0]]
    for _ in xrange(len(your_items)-1):
        ordered_items.append(items_by_start[ordered_items[-1].end])
    

    【讨论】:

    • 同样假设没有重复的starts。
    • 非常感谢,我会试一试。我认为这不会关心同一组中的 2 个独立列表,对吗?
    • @JoanVenge 如果你有两个单独的列表,你会遇到循环重复次数的问题;您必须为此使用稍微复杂一点的逻辑。
    • 谢谢 Amber,如果我使用了很好的假设,您的逻辑仍然非常有用。
    猜你喜欢
    • 1970-01-01
    • 2012-10-02
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多