首页 > 解决方案 > 过滤列表以获取独特和最新的项目

问题描述

从列表中仅获取独特和最新项目的最佳方法是什么?我想出的一种方法:

from itertools import groupby
from collections import namedtuple
from datetime import date

Event = namedtuple('Event', ('id', 'type', 'date'))

event_1 = Event(id=1, type='income', date=date(2020, 1, 5))
event_2 = Event(id=1, type='income', date=date(2020, 1, 10))
event_3 = Event(id=1, type='income', date=date(2020, 1, 8))

event_4 = Event(id=2, type='outcome', date=date(2020, 1, 9))
event_5 = Event(id=2, type='outcome', date=date(2020, 1, 15))


data = [event_1, event_2, event_3, event_4, event_5]


grouped = groupby(sorted(data, key=lambda e: (e.id, e.type, -e.date)), key=lambda e: (e.id, e.type))

unique_latest = [next(item[1]) for item in grouped]

所以结果应该是:unique_latest = [event_2, event_5].

因此,我按唯一性标准(id、类型)分组并取每个组的第一项。

但是这种方法并不能保证第一个项目是其组中的最新项目。

试过做sorted(data, key=lambda e: (e.id, e.type, -e.date)),但是python不允许-e.date

标签: pythonpython-3.xitertools

解决方案


这只是因为 否定(一元减号)未定义datetime

从更大的日期(比如明年)中减去日期,然后使用timedelta结果进行排序。

grouped = groupby(sorted(data, key=lambda e: (e.id, e.type,
                            date(2021, 12, 31) - e.date)),
                         key=lambda e: (e.id, e.type))

结果:

[Event(id=1, type='income', date=datetime.date(2020, 1, 10)),
 Event(id=2, type='outcome', date=datetime.date(2020, 1, 15))]

推荐阅读