我尝试根据一些重要的比较逻辑对对象列表进行排序,但发现这很困难,因为在 Python 中,自定义排序函数只需要一个参数。例如,在 Java 中,排序函数将引用 object1 和 object2,从而可以直接比较它们。
class Point:
def __init__(self, char, num, pt_type):
self.char = char
self.num = num
self.pt_type = pt_type # 'start' or 'end'
def __str__(self):
return str([self.char, str(self.num), self.pt_type])
def __repr__(self):
return str(self)
arr = [Point('C', 1, 'end'), Point('C', 9, 'start'),
Point('B', 7, 'end'), Point('B', 2, 'end'),
Point('A', 3, 'start'), Point('A', 6, 'start')]
def my_sort(key):
# Sort by first element (letter).
#
# If the letter is the same, fallback to sorting by the
# 2nd element (number), but the logic of this comparison depends
# on `pt_type`:
# -If Point1 and Point2 both have type 'start', pick the higher number first.
# -If Point1 and Point2 both have type 'end', pick the lower number first.
# -If Point1 and Point2 have different types, pick the 'start' type first.
return key.char
print(sorted(arr, key=my_sort))
预期的排序顺序应该是:
[Point('A', 6, 'start'), Point('A', 3, 'start')
Point('B', 2, 'end'), Point('B', 7, 'end'),
Point('C', 9, 'start'), Point('C', 1, 'end')]
我什至不知道如何开始实现所需的逻辑,所以我将不胜感激插入正确的方向。
请您参考如下方法:
我会使用下面的 key 函数:
class Point:
def __init__(self, char, num, pt_type):
self.char = char
self.num = num
self.pt_type = pt_type # 'start' or 'end'
def __str__(self):
return str([self.char, str(self.num), self.pt_type])
def __repr__(self):
return str(self)
arr = [Point('C', 1, 'end'), Point('C', 9, 'start'),
Point('B', 7, 'end'), Point('B', 2, 'end'),
Point('A', 3, 'start'), Point('A', 6, 'start')]
def key(p):
return p.char, int(p.pt_type != 'start'), p.num if p.pt_type == 'end' else -1 * p.num
result = sorted(arr, key=key)
print(result)
输出
[['A', '6', 'start'], ['A', '3', 'start'], ['B', '2', 'end'], ['B', '7', 'end'], ['C', '9', 'start'], ['C', '1', 'end']]
key 函数创建一个用作键的元组,第一个元素是字母,如果节点类型为“start”,则第二个元素为 0,如果节点类型为“end”,则为 1。如果最后一个元素是“开始”类型,则它是负数;如果它是“结束”类型,则它是正数。
