我在
Python 3.5.2中有一个字典列表,我试图“重复数据删除”.所有字典都是唯一的,但是有一个特定的键我想要重复删除,保持字典具有最多的非空值.
例如,我有以下字典列表:
d1 = {"id":"a","foo":"bar","baz":"bat"} d2 = {"id":"b","baz":None} d3 = {"id":"a","baz":None} d4 = {"id":"b","baz":"bat"} l = [d1,d2,d3,d4]
我想将l过滤到只有具有唯一id键的字典,保持具有最少空值的字典.在这种情况下,函数应该保持d1和d4.
我试图创建一个新的键,val对“值计数”,如下所示:
for d in l: d['val_count'] = len(set([v for v in d.values() if v]))
现在我要坚持的是如何过滤我的唯一ID的dicts列表,其中val_count键是更大的值.
我对其他方法持开放态度,但由于资源限制,我无法将pandas用于此项目.
预期产量:
l = [{"id":"a","baz":"bat"},{"id":"b","baz":"bat"}]
解决方法
我会使用
groupby并从每组中选择第一个:
1)首先按键排序(创建组)和减少空值计数(您的既定目标):
>>> l2=sorted(l,key=lambda d: (d['id'],-sum(1 for v in d.values() if v)))
2)然后按ID分组,并在排序列表的groupby中将每个迭代器的第一个元素显示为d:
>>> from itertools import groupby >>> [next(d) for _,d in groupby(l2,key=lambda _d: _d['id'])] [{'id': 'a','foo': 'bar','baz': 'bat'},{'id': 'b','baz': 'bat'}]
如果你想要一个’tie breaker’来选择第一个dict,否则它们具有相同的空值,你可以添加一个枚举装饰器:
>>> l2=sorted(enumerate(l),key=lambda t: (t[1]['id'],t[0],-sum(1 for v in t[1].values() if v))) >>> [next(d)[1] for _,key=lambda t: t[1]['id'])]
我怀疑是否需要额外的步骤,因为Python的排序(和排序)是stable sort,并且序列将仅根据键和空值计数从列表顺序更改.因此,除非您确定需要使用第二个版本,否则请使用第一个版本.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。