[英]Removing repeated dictionaries in a list of dictionaries based on 2 keys
我有一个字典列表,像这样:
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'} ,...]
性能很重要。
我将使用排序后的值(反转)重建带有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
这两个答案都有效,我想虽然我是一个真正的初学者,但我宁愿选择一些简单的方法。 我会做的事情与@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
此转换将您的项目放入以key为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()
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)
这是一种更详细的方法
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)
您可以使用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'}]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.