过滤列表以获得独特的和最新的项目
filter list to get unique and latest items
从列表中只获取唯一和最新项目的最佳方法是什么?
我想出的一种方法:
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
。
这只是因为 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))]
如果您使用 datetime
对象而不是 date
,您可以使用 datetime.timestamp()
将值转换为浮点数,然后可以取反进行排序:
from itertools import groupby
from collections import namedtuple
from datetime import datetime
Event = namedtuple('Event', ('id', 'type', 'date'))
event_1 = Event(id=1, type='income', date=datetime(2020, 1, 5))
event_2 = Event(id=1, type='income', date=datetime(2020, 1, 10))
event_3 = Event(id=1, type='income', date=datetime(2020, 1, 8))
event_4 = Event(id=2, type='outcome', date=datetime(2020, 1, 9))
event_5 = Event(id=2, type='outcome', date=datetime(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.timestamp())), key=lambda e: (e.id, e.type))
unique_latest = [next(item[1]) for item in grouped]
print(unique_latest)
输出:
[
Event(id=1, type='income', date=datetime.datetime(2020, 1, 10, 0, 0)),
Event(id=2, type='outcome', date=datetime.datetime(2020, 1, 15, 0, 0))
]
从列表中只获取唯一和最新项目的最佳方法是什么? 我想出的一种方法:
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
。
这只是因为 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))]
如果您使用 datetime
对象而不是 date
,您可以使用 datetime.timestamp()
将值转换为浮点数,然后可以取反进行排序:
from itertools import groupby
from collections import namedtuple
from datetime import datetime
Event = namedtuple('Event', ('id', 'type', 'date'))
event_1 = Event(id=1, type='income', date=datetime(2020, 1, 5))
event_2 = Event(id=1, type='income', date=datetime(2020, 1, 10))
event_3 = Event(id=1, type='income', date=datetime(2020, 1, 8))
event_4 = Event(id=2, type='outcome', date=datetime(2020, 1, 9))
event_5 = Event(id=2, type='outcome', date=datetime(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.timestamp())), key=lambda e: (e.id, e.type))
unique_latest = [next(item[1]) for item in grouped]
print(unique_latest)
输出:
[
Event(id=1, type='income', date=datetime.datetime(2020, 1, 10, 0, 0)),
Event(id=2, type='outcome', date=datetime.datetime(2020, 1, 15, 0, 0))
]