【问题标题】:Sorting python list of lists with custom comparator使用自定义比较器对列表的 python 列表进行排序
【发布时间】:2020-07-09 17:01:54
【问题描述】:

我正在尝试对以下列表进行排序:

points = [[1, 4, 'start'], [1, 6, 'start'], [2, 8, 'end'], [2, 5, 'end'], [3, 4, 'end'], [3, 9, 'start']]

预期输出:

[[1, 6, 'start'], [1, 4, 'start'], [2, 5, 'end'], [2, 8, 'end'], [3, 9, 'start'], [3, 4, 'end']]

排序条件为:

  1. 如果 p1[0] == p2[0] 和 p1[2] == 'start' 和 p2[2] == 'start',则 p1[1] 或 p2[1] 更大价值应该是第一位的。

  2. 如果 p1[0] == p2[0] 和 p1[2] == 'end' 和 p2[2] == 'end',则 p1[1] 或 p2[1] 具有较小的价值应该是第一位的。

  3. 如果 p1[0] == p2[0] 和 p1[2] == 'start' 和 p2[2] == 'end',那么带有 'start' 的点应该在前。

我尝试编写一个自定义比较器(得到正确答案),只是想知道这是正确的方法吗?能不能简单点?

def mycmp(p1, p2):
    if p1[0] < p2[0]:
        return -1

    if p1[0] == p2[0]:
        if p1[2] == 'start' and p2[2] == 'start' and p1[1] > p2[1]:
            return -1
        elif p1[2] == 'end' and p2[2] == 'end' and p1[1] < p2[1]:
            return -1
        elif p1[2] == 'start' and p2[2] == 'end':
            return -1
    return 0

points.sort(key=cmp_to_key(mycmp))

【问题讨论】:

  • 这个函数永远不会返回1?这似乎不太适合排序回调。

标签: python-3.x list sorting comparator


【解决方案1】:
points.sort(key = lambda x: (x[0], x[2] == 'end', -x[1] if x[2] == 'start' else x[1]))

你能用lambda吗,关键是要按顺序指定优先级,感谢@Jack。

在 lambda 函数中总共使用了 3 个键。

你先排序x[0] in ascending order

如果有平局,你给high priority to x[2] = end

最后你排序x[1] in descending order if x[2]=start and ascending if x[2]=end

Logic is to specify your priorities in order inside the lambda function

【讨论】:

  • 开始应该在结束之前;这似乎不在这里考虑?
  • 优先顺序是什么,是0>1>2,数字表示索引。
  • 还有,对于[2] == 'start',那么[1]是降序的,否则是升序的。
  • 这可能会解决它:(x[0], x[2] == 'end', -x[1] if x[2] == 'start' else x[1])
  • points.sort(key = lambda x: (x[0], x[2] == 'end', -x[1] if x[2] == 'start' else x[1])) 是的,这似乎有效,我会更新我的答案,谢谢。
猜你喜欢
  • 2020-07-11
  • 2011-07-09
  • 2019-05-06
  • 2018-09-10
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多