社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

python对象的自定义过滤函数

Seth Killian • 5 年前 • 1707 次点击  


# 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
 
1707 次点击  
文章 [ 4 ]  |  最新文章 5 年前
kaya3 Paulius
Reply   •   1 楼
kaya3 Paulius    5 年前

可以按分数排序、转换为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    5 年前

像这样的:

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    5 年前

你可以用 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    5 年前

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