python对象的自定义筛选函数

2024-04-27 14:37:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个元组列表,比如(id),我想删除重复的id。在有多对具有相同id的情况下,我希望保留具有较高分数对象的一对。我如何才能有效地实现这一点


# For the sake of example - assume that a hashing function is implemented based on the score

class Object
   def __init__(self):
       score = 0
   def __repr__(self):
       return f'<Object {self.score}>'

pairs = [(1, <Object 1>), (1, <Object 1>), (3, <Object 7>), (9, <Object 3>), (9, <Object 4>)]

filtered_pairs = [(1, <Object 1>), (3, <Object 7>), (9, <Object 4>)]

我知道我可以对这些对调用set,但这只会处理id和score都相等的情况(比如对象1)。我如何过滤它,但在有匹配ID的情况下,取较高的分数

我知道我可以从itertools中进行分组,并使用分数作为键实现排序,然后只从每个组中提取最后一项,但我想知道是否有更有效的方法


Tags: ofthe对象selfid列表forobject
3条回答

大概是这样的:

from collections import namedtuple

Pair = namedtuple('Pair', ['id', 'score'])

pairs = [Pair(*t) for t in [(1, 1), (1, 1), (3, 7), (9, 3), (9, 4)]]

best_pairs = {}
for p in pairs:
    if p.id not in best_pairs or p.score > best_pairs[p.id]:
        best_pairs[p.id] = p.score

pairs = [Pair(*t) for t in best_pairs.items()]

print(pairs)

namedtuple只是作为Object的更简洁版本存在,而转换回pairs作为配对列表仅在那里,以防您不喜欢结果是字典best_pairs

结果:

[Pair(id=1, score=1), Pair(id=3, score=7), Pair(id=9, score=4)]

既然你考虑的是一套,我想原来的顺序并不重要。如果是这种情况,一个选项是向类中添加一个__lt__方法,这样就可以按分数比较对象。然后将元组按相反顺序排序,按整数分组,并从每组中取出第一项。在代码中查看比解释更容易:

from itertools import groupby

class myObject:
    def __init__(self, score):
        self.score = score
    def __repr__(self):
        return f'<Object {self.score}>'
    def __lt__(self, other):
        return self.score < other.score

pairs = [(1, myObject(1)), (1, myObject(1)), (3, myObject(7)), (9, myObject(3)), (9, myObject(4))]

[next(v) for k, v in groupby(sorted(pairs, reverse=True), key=lambda x: x[0])]

结果

[(9, <Object 4>), (3, <Object 7>), (1, <Object 1>)]

您可以使用itertools.groupby按第一个值分组,并对结果使用max

from itertools import groupby


class Object:

    def __init__(self, score):
        self.score = score

    def __repr__(self):
        return f'<Object {self.score}>'


pairs = [(1, Object(1)), (1, Object(1)), (3, Object(7)), (9, Object(3)), (9, Object(4))]

filtered_pairs = [max(list(elem), key=lambda x: x[1].score) for grp, elem in groupby(pairs, lambda x: (x[0]))]
print(filtered_pairs)

输出:

[(1, <Object 1>), (3, <Object 7>), (9, <Object 4>)]

相关问题 更多 >