Python 从两个目录列表中删除匹配项

Python 从两个目录列表中删除匹配项,python,dictionary,Python,Dictionary,我需要使用两个字典,并过滤掉无法识别名称的“垃圾”项: 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 = [ {'annot

我需要使用两个字典,并过滤掉无法识别名称的“垃圾”项:

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': '----'}
]
所以在这种情况下,我需要从数据中删除注释_id 13

我尝试迭代列表并将其删除,但我知道这在python中不起作用。我也试过理解列表,但同样失败了。我做错了什么?我的代码如下:

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

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

您可以创建一个集合来保存垃圾名称,然后根据该名称集合筛选数据(如果名称是需要筛选的条件):


如评论中所述,您也可以按照您原来的方法执行
[数据中的项如果全部(垃圾中的项['name']!=g['name']对于g)]
,但由于双循环的时间复杂度为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

删除DICT数组中特定项的简单而优雅的方法,其中
垃圾
是要从
数据
中删除的DICT项列表:

 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'}
]
结果:

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'}
]

一个简单的
过滤器如何

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}]

垃圾的标准是什么?是否总是如您在示例中所示的四个破折号?垃圾列表使用不同的函数创建,并包含许多不同的名称。
item['name']!=g、 ['name']
应该是
项['name']!=g['name']
。另外,在理解列表的开头放上一个方括号。有很多方法可以做到这一点。修正您的初始方法:
data=[item for item in data if all(item['name']!=g['name']for g in garbage)]
请记住,
garbage
是一个包含1个dict的列表,而不仅仅是一个dict。garbage是一个列表,因此它可以包含更多的条目。这个解决方案效果很好。它是经过测试的,我认为这个问题只需要匹配一个单独的k/v对值,而不是整个dict作为一个项目,所以你的解决方案是好的+1
list.remove
是一个很好的方法,但我从未在实践中使用过它,我更喜欢创建新的过滤
list
object,我没有意识到它会与“in”匹配得那么好。非常感谢。