2011-05-13 115 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