2011-05-13 110 views
3

我是Python新手,我不確定使用字典的字典是個好主意,但這是我的問題。 我有字典的字典,我想通過內部字典的鍵來過濾:過濾字典的字典

a ={ 'key1' : {'id1' :[0,1,2] , 'id2' :[0,1,2], 'id3' :[4,5,6]} 
    'key2' : {'id3' :[0,1,2] , 'id4' :[0,1,2]} 
    'key3' : {'id3' :[0,1,2] , 'id1' :[4,5,6]} 
    } 

對於爲例,我想「ID1」過濾有:

result = { 'key1' : {'id1' :[0,1,2] } 
      'key3' : {'id1' :[4,5,6]} 
     } 

我有試圖過濾方法,通過我得到的所有價值:

r = [('key1' ,{'id1' :[0,1,2] , 'id2' :[0,1,2], 'id3' :[4,5,6]}) 
    ('key3' , {'id3' :[0,1,2] , 'id1' :[4,5,6]}) 
    ] 

而且過濾方法返回一個列表,我想保持格式的字典。

在此先感謝

+0

我認爲你需要使用一些數據處理技術。鑑於您的輸出規格,您可能需要使用自定義對象。 – Pwnna 2011-05-13 13:36:14

回答

5

試試這個:

>>> { k: v['id1'] for k,v in a.items() if 'id1' in v } 
{'key3': [4, 5, 6], 'key1': [0, 1, 2]} 

對於Python 2.x的,你可能更願意使用iteritems(),而不是items(),你仍然需要一個相當最近的Python(2.7我認爲)一個字典解析:老年蟒蛇使用:

dict((k, v['id1']) for k,v in a.iteritems() if 'id1' in v) 

如果你想提取多個值,那麼我想你最好只寫循環s出全:

def query(data, wanted): 
    result = {} 
    for k, v in data.items(): 
     v2 = { k2:v[k2] for k2 in wanted if k2 in v } 
     if v2: 
      result[k] = v2 
    return result 

捐贈:

>>> query(a, ('id1', 'id2')) 
{'key3': {'id1': [4, 5, 6]}, 'key1': {'id2': [0, 1, 2], 'id1': [0, 1, 2]}} 
+0

這很好,但實際上我不想過濾只有一個值,但一個列表值(例如。['id1,'id2']) – Othman 2011-05-13 13:58:14

+0

好吧,我添加了一些更長的代碼來處理值列表。 – Duncan 2011-05-13 14:22:20

1

可以藉助字典理解做:

def query(data, query): 
    return {key : {query : data[key][query]} 
      for key in data if query in data[key]} 

你要看看字典的每個條目,可能花費很多時候如果你有很多條目或做這個很多。具有索引的數據庫可以加快速度。

+0

其實我解析一個大的csv文件(30 MB),所以我怎麼能提高速度? – Othman 2011-05-13 13:46:25

1
field = 'id1' 
dict((k,{field: d[field]}) for k,d in a.items() if field in d) 
+0

適用於Pythons <2.7,沒有詞典理解。 – martineau 2011-05-13 14:08:23

2

根據你給鄧肯的精度,這裏是使用字典解析名單上的另一個過濾:

>>> my_list = ['id1', 'id2'] 
>>> {k1 : {k2: v2 for (k2, v2) in a[k1].iteritems() if k2 in my_list} for k1 in a} 
{'key3': {'id1': [4, 5, 6]}, 'key2': {}, 'key1': {'id2': [0, 1, 2], 'id1': [0, 1, 2]}} 

編輯:您還可以用另一個字典compreehension刪除空值,但「開始「難以閱讀... :-)

>>> {k3: v3 for k3, v3 in {k1 : {k2: v2 for (k2, v2) in a[k1].iteritems() if k2 in my_list} for k1 in a}.iteritems() if v3} 
{'key3': {'id1': [4, 5, 6]}, 'key1': {'id2': [0, 1, 2], 'id1': [0, 1, 2]}} 
+0

可憐的空字典潛伏在中間。我認爲在這一點上,放棄字典解析是值得的,只需將所有內容全寫出來:參見我的更新答案 – Duncan 2011-05-13 14:23:34