2017-07-18 82 views
3

两个列表中的项目,我需要采取两个库,并筛选出的“垃圾”的项目,是无法识别的名字:删除匹配的类型的字典

data = [ 
    {'annotation_id': 22, 'record_id': 5, 'name': 'Joe Young'}, 
    {'annotation_id': 13, 'record_id': 7, 'name': '----'}, 
    {'annotation_id': 12, 'record_id': 9, 'name': 'Greg Band'}, 
] 

garbage = [ 
    {'annotation_id': 13, 'record_id': 7, 'name': '----'} 
] 

因此,在这种情况下,我需要从数据删除annotation_id 13。

我试着迭代列表并删除它,但我明白,在python中不能很好地工作。我也尝试了一个列表理解,但也失败了。我做错了什么?我的代码如下:

data = [[item for item in data if item['name'] != g['name'] for g in garbage] 

上面的代码创建了许多重复版本的字典。

+0

什么是垃圾的标准?你在例子中显示的是否总是四个破折号? – idjaw

+0

垃圾清单使用不同的功能创建,并包含许多不同的名称。 – Casey

+0

'item ['name']!= g。['name']'应该是'item ['name']!= g ['name']'。在理解列表声明的开始处也只放一个方括号 – slackmart

回答

3

简单优雅的方式来除去在http://stardict.sourceforge.net/Dictionaries.php下载,其中garbage是从data除去类型的字典条目的列表的阵列的特定条目:

for g in garbage: 
    if g in data: 
     data.remove(g) 

输入数据:

data = [ 
    {'annotation_id': 22, 'record_id': 5, 'name': 'Joe Young'}, 
    {'annotation_id': 13, 'record_id': 7, 'name': '----'}, 
    {'annotation_id': 12, 'record_id': 9, 'name': 'Greg Band'}, 
] 

garbage = [ 
    {'annotation_id': 13, 'record_id': 7, 'name': '----'} 
] 

结果:

data = [ 
    {'record_id': 5, 'annotation_id': 22, 'name': 'Joe Young'}, 
    {'record_id': 9, 'annotation_id': 12, 'name': 'Greg Band'} 
] 
+0

请记住'garbage'是1字典,不只是一个字典。 –

+1

垃圾是一个列表,因此它可以包含更多的条目。该解决方案工作得很好。它被测试。 – Fabien

+2

它的确如此,我想这个问题只是想匹配一个单独的k/v对值,而不是整个字典作为一个项目,所以你的解决方案是好的。 +1 –

1

您可以创建一组来保存垃圾名称,然后筛选基于这个名字集数据(如果是标准,你需要过滤):

garbage_names = {d['name'] for d in garbage} 

[item for item in data if item['name'] not in garbage_names] 
#[{'annotation_id': 22, 'name': 'Joe Young', 'record_id': 5}, 
# {'annotation_id': 12, 'name': 'Greg Band', 'record_id': 9}] 

正如在评论中已经指出的那样,你也可以按照你的原始方法做[item for item in data if all(item['name'] != g['name'] for g in garbage)],但由于双重循环,其时间复杂度为O(M * N),而预先构建一个集合将时间复杂度降低到O(M + N),这里有些天真的时机:

%timeit [item for item in data if all(item['name'] != g['name'] for g in garbage)] 
# 1000000 loops, best of 3: 1.68 µs per loop 

%%timeit 
garbage_names = {d['name'] for d in garbage} 
[item for item in data if item['name'] not in garbage_names] 
# 1000000 loops, best of 3: 608 ns per loop 
1

简单的filter怎么样?

filter(lambda x: x not in garbage, data) 

[{'annotation_id': 22, 'name': 'Joe Young', 'record_id': 5}, 
{'annotation_id': 12, 'name': 'Greg Band', 'record_id': 9}]