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,并且序列将仅根据键和空值计数从列表顺序更改.因此,除非您确定需要使用第二个版本,否则请使用第一个版本.

相关文章

功能概要:(目前已实现功能)公共展示部分:1.网站首页展示...
大体上把Python中的数据类型分为如下几类: Number(数字) ...
开发之前第一步,就是构造整个的项目结构。这就好比作一幅画...
源码编译方式安装Apache首先下载Apache源码压缩包,地址为ht...
前面说完了此项目的创建及数据模型设计的过程。如果未看过,...
python中常用的写爬虫的库有urllib2、requests,对于大多数比...