Reputation: 7136
I have a list of dictionaries and need only the items with and unique item names but only the dictionary which has latest endtime.
eg:
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'} )
so the result should be
only
({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'})
any hints?
UPDATE:
what if the endtime is in datetime format already?
{item: 'name1', starttime : datetime.datetime(2013, 10, 30, 7, 13, 21), endtime:datetime.datetime(2013, 10, 30, 7, 13, 21}
Upvotes: 0
Views: 96
Reputation: 4182
I think itertools.groupby(iterable[, key])
can be helpful here.
You can group data by item with key item
And then pick desired item
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])
if end_time
item is string You should strip first
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 k, g in itertools.groupby(query_result, key=lambda x: x['item']):
final_result.append(sorted(g, key=endtime_sort_key, reverse=True)[0])
Upvotes: 1
Reputation: 1457
from time import strptime
result = []
for i in query_result:
tmp = {}
for j in (k for k in query_result if k['item'] == i['item']):
if strptime(j['endtime'], '%Y-%m.%d %I:%M:%S') > strptime(i['endtime'], '%Y-%m.%d %I:%M:%S'):
tmp['item'] = j['item']
tmp['starttime'] = j['starttime']
tmp['endtime'] = j['endtime']
if(tmp and tmp not in result):
result.append(tmp)
result = (tuple(result))
Upvotes: 0
Reputation: 229581
Sort by descending endtime, then take the first of each name:
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'])
Upvotes: 1