微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – 根据另一个键过滤字典列表以删除键中的重复项

我在 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 举报,一经查实,本站将立刻删除。

相关推荐