2017-07-18 79 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}]