我们需要处理一个包含多个词典的列表,每个词典都有一个 item 键值和一个 endtime 键值。我们需要对这些词典按 endtime 键值进行排序,然后取每个 item 键值中唯一项对应的词典,同时确保取到的词典具有最新的 endtime 键值。
例如,给定以下 query_result 列表:
query_result = (
{item: 'name1', starttime ='2013-10-29 07:28:14', endtime = '2013-10.29 08:28:14'},
{item: 'name1', starttime ='2013-10-29 08:28:14', endtime = '2013-10.29 09:28:14'},
{item: 'name1', starttime ='2013-10-29 07:28:14', endtime = '2013-10.29 08:28:14'},
{item: 'name2', starttime ='2013-10-29 07:28:14', endtime = '2013-10.29 07:29:14'},
{item: 'name2', starttime ='2013-10-29 07:28:14', endtime = '2013-10.29 07:45:14'},
{item: 'name2', starttime ='2013-10-29 07:28:14', endtime = '2013-10.29 08:28:14'}
)
期望输出结果为:
({item1: 'name1', starttime ='2013-10-29 07:28:14', endtime = '2013-10.29 09:28:14'},
{item2: 'name2', starttime ='2013-10-29 07:28:14', endtime = '2013-10.29 08:28:14'})
2. 解决方案
方法一:使用 sorted() 函数和自定义排序函数
我们可以使用 sorted() 函数对 query_result 列表进行排序,并提供一个自定义的排序函数 endtime_sort_key() 来比较词典中的 endtime 键值。然后,我们可以使用 set() 和 used_names 变量来记录已经处理过的 item 键值,并将具有最新 endtime 键值的词典添加到 final_result 列表中。
import datetime
def endtime_sort_key(item):
return datetime.datetime.strptime(item['endtime'], "%Y-%m.%d %H:%M:%S")
used_names = set()
final_result = []
for item in sorted(query_result, key=endtime_sort_key, reverse=True):
if item['item'] not in used_names:
final_result.append(item)
used_names.add(item['item'])
方法二:使用 itertools.groupby() 函数
我们还可以使用 itertools.groupby() 函数来对 query_result 列表进行分组,其中分组依据是 item 键值。然后,我们可以对每个分组中的词典按 endtime 键值进行排序,并取具有最新 endtime 键值的词典。
from itertools import groupby
used_names = set()
final_result = []
for k, g in itertools.groupby(query_result, key=lambda x: x['item']):
final_result.append(sorted(g, key=lambda item: item['endtime'], reverse=True)[0])
方法三:使用 functools.cmp_to_key() 函数
functools.cmp_to_key()函数可以将函数转化为一个比较函数。
import functools
query_result.sort(key=functools.cmp_to_key(lambda x, y: datetime.datetime.strptime(y['endtime'], "%Y-%m.%d %H:%M:%S") - datetime.datetime.strptime(x['endtime'], "%Y-%m.%d %H:%M:%S")))
result = []
used_names = set()
for item in query_result:
if item['item'] not in used_names:
used_names.add(item['item'])
result.append(item)
注意:
如果 endtime 键值是 datetime 对象,则需要在比较时使用 datetime.datetime.strptime() 函数将其转换为字符串格式。
def endtime_sort_key(item):
return datetime.datetime.strptime(item['endtime'], "%Y-%m.%d %H:%M:%S")