【问题标题】:How can I order a list based on another lists order?如何根据另一个列表顺序订购列表?
【发布时间】:2020-12-28 22:00:43
【问题描述】:

我有一个奇怪的问题,所以我只是演示一下,让你更容易理解。我有两个列表:

>>> a = [1, 2, 20, 6, 210]
>>> b = [20, 6, 1]

我正在寻找的结果是 3(列表 a 中最后一个匹配项的位置基于 b 中的匹配)

b 总是有较少的数据,因为它包含列表 a 的所有重复项。我想知道 B 中的哪个项目与列表 a 中的最匹配。所以在这个例子中,它将是 6,因为 6 在 A 的列表中最远。

有没有一种简单的方法可以做到这一点 - 我最初的方法是嵌套循环,但我怀疑有更简单的方法?

【问题讨论】:

  • 这是一个简单的sorted(b, key=a.index)[-1]
  • 你也可以使用来自 more_itertools 的sort_together
  • 对于所描述的特定情况,最简单(如果不一定是最有效)的代码就是max(b, key=a.index)(或b.sort(key=a.index)/sorted(b, key=a.index),如果您需要对整个列表进行排序,而不仅仅是最大描述的值)。
  • @Lostsoul 如果您甚至从a 中删除了重复项,那么a.index 就可以了。
  • 谢谢!抱歉,当推荐的问题没有解决我的问题时,我不确定为什么该问题已关闭。我希望你们可以发布实际答案并获得支持,但无论如何,非常感谢你们解决了我的问题。 @ShadowRanger 的回答会被接受。

标签: python list


【解决方案1】:

最简单(如果不一定是最有效)的代码就是:

 max(b, key=a.index)

或者,如果您希望对整个 list 进行排序,而不仅仅是描述的最大值,可以选择以下之一:

b.sort(key=a.index)

sorted(b, key=a.index)

如果引用 list 中可能出现重复,并且您需要获取值的最后一个索引,请将 index 替换为 one of these simulations of rindex

更新:解决您获得职位而不是价值的要求,有一种替代方法可以解决这个问题,需要更少的工作。基本上是对one of the better solutions to emulating rindex的修改:

bset = frozenset(b)
last_a_index = len(a) - next(i for i, x in enumerate(reversed(a), 1) if x in bset)

这将工作归结为O(m + n)(相对于其他解决方案的O(m * n)),它使a上的循环短路;它反向扫描,直到在b 中找到一个值,然后立即生成索引。它可以简单地扩展为使用a[last_a_index] 生成值,因为它在b 中的位置并不重要。更复杂的代码,但速度更快,尤其是在 a/b 可能很大的情况下。

【讨论】:

  • @superbrain:是的,这不在最初的问题中,评论说他们喜欢我的解决方案,所以我只是发布了它。编辑添加了一个高效的索引生成解决方案(它也可以为较大的输入产生理论上更好性能的值,尽管对于小输入,your simple code that pushes the work to the C layer 几乎肯定更快;我赞成它)。
  • 非常感谢@shadowRanger - 对我来说,无论是位置还是价值都很好。感谢您向我展示如何执行这两个选项。
  • 啊,对不起。我没有意识到这是添加的。一个可能更简单的高效解决方案替代方案:next(i for i in reversed(range(len(a))) if a[i] in bset)
【解决方案2】:

既然你要求职位

>>> max(map(a.index, b))
3

【讨论】:

    猜你喜欢
    • 2018-09-01
    • 2015-02-27
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 2018-01-03
    • 1970-01-01
    相关资源
    最近更新 更多