Python社区  »  Python

python对象的自定义过滤函数

Seth Killian • 1 月前 • 25 次点击  


# 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

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

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/54697
 
25 次点击  
分享到微博
文章 [ 4 ]  |  最新文章 1 月前
kaya3 Paulius
Reply   •   1 楼
kaya3 Paulius    1 月前

可以按分数排序、转换为dict(以便最大分数为dict值)和转换回元组列表:

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


pairs = [(1, Object(1)), (1, Object(1)), (3, Object(7)), (9, Object(4)), (9, Object(3))]
filtered_pairs = list(dict(sorted(pairs)).items())
Grismar
Reply   •   2 楼
Grismar    1 月前

像这样的:

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)]
Guy
Reply   •   3 楼
Guy    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>)]
Mark Meyer
Reply   •   4 楼
Mark Meyer    1 月前

既然你在考虑一套,我想原来的顺序并不重要。如果是这样,一个选项是添加 __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>)]