我有一个字典列表,如下所示:
my_list = [{'key1':'1', 'date':'2015-01-09'}, {'key1':'3', 'date':'2015-01-09'}, {'key1':'1', 'date':'2014-03-19'}, \
{'key1':'4', 'date':'2015-05-09'} ,...]
在某些字典中,key1的值会重复,我想根据日期(字典的另一个键)从列表中删除它们,并且只保留具有最早日期的字典。 结果:
my_list = [{'key1':'3', 'date':'2015-01-09'}, {'key1':'1', 'date':'2014-03-19'}, {'key1':'4', 'date':'2015-05-09'} ,...]
表现很重要。
答案 0 :(得分:5)
我会使用key1
作为字典理解中的关键重建字典,使用排序值(反向),以便最后返回最早的日期,覆盖相同的键:只保留最早的日期:
my_list = [{'key1':'1', 'date':'2015-01-09'}, {'key1':'3', 'date':'2015-01-09'}, {'key1':'1', 'date':'2014-03-19'}, \
{'key1':'4', 'date':'2015-05-09'}]
my_dict = {d["key1"]:d for d in sorted(my_list,key=lambda l:l["date"],reverse=True)}
print(list(my_dict.values()))
结果(我认为排序没关系,否则我不能使用字典,因为订单没有保留):
[{'key1': '1', 'date': '2014-03-19'}, {'key1': '3', 'date': '2015-01-09'}, {'key1': '4', 'date': '2015-05-09'}]
(请注意,使用字典顺序对日期进行排序是正常的,因为它们是YYYY-MM-DD格式,它使事情变得更容易:无需解析日期)
如果内存不足,另一种解决方案是避免排序部分,因为它预先创建了列表的排序副本(不重复数据,但仍然可以占用一些内存)。
在这种情况下,经典循环可以做得更慢但内存更少(并且不需要排序)。当密钥不在目标词典中时,使用带有默认值的get
返回'A'
以强制插入(A
排名高于任何数字)。
my_dict = {}
for l in my_list:
k = l['key1']
d = l['date']
if my_dict.get(k,'A') > d:
my_dict[k] = d
答案 1 :(得分:1)
这两个答案都有效,我想虽然当我是一个真正的初学者时,我会更喜欢一些更简单的东西。我会做的与@ Jean_Francois的答案相似,但我觉得有点简单(虽然它有更多的代码行)
我会从列表中构建一个字典,当我添加它时,我会检查日期。他指出,数据检查很简单
from collections import defaultdict
min_date_dict = defaultdict(dict)
for item_date in my_list:
key = item_date['key1']
date = item_date['date']
if key in min_date:
if min_date[key]['date'] > date:
min_date[key] = item_date
else:
min_date[key] = item_date
此转换将您的项目放入字典中,并将键作为key1的值
defaultdict(<type 'dict'>, {'1': {'date': '2014-03-19', 'key1': '1'}, '3': {'date': '2015-01-09', 'key1': '3'}, '4': {'date': '2015-05-09', 'key1': '4'}})
现在把它放回一个列表
item_date_list = min_date.values()
答案 2 :(得分:0)
import pandas as pd
list(pd.DataFrame(my_list).sort_values(by='date').drop_duplicates(subset=['key1'], keep='first').apply(lambda s: s.to_dict(), axis=1).values)
答案 3 :(得分:0)
这是一种更详细的方法
my_list = [{'key1':'1', 'date':'2015-01-09'},
{'key1':'3', 'date':'2015-01-09'},
{'key1':'1', 'date':'2014-03-19'},
{'key1':'4', 'date':'2015-05-09'}]
mins = {}
for i, d in enumerate(my_list):
if d['key1'] not in mins or mins[d['key1']]['date'] > d['date']:
mins[d['key1']] = {'date': d['date'], 'ind': i}
indices = sorted([d['ind'] for d in mins.values()])
filtered = [my_list[i] for i in indices]
print(filtered)
答案 4 :(得分:0)
您可以使用itertools groupby按键分组,然后获取每个组的最小日期。见下面的例子
final_list = [min(list(g), key = lambda x: x['date']) for k, g in groupby(sorted(my_list, key=lambda x: x['key1']), lambda x: x['key1'])]
结果
[{'date': '2014-03-19', 'key1': '1'}, {'date': '2015-01-09', 'key1': '3'}, {'date': '2015-05-09', 'key1': '4'}]