Dividir dict por valor de una de las teclas.

Tengo un diccionario con datos de la misma longitud (pero diferentes tipos), algo así como:

data = { "id": [1,1,2,2,1,2,1,2], "info": ["info1","info2","info3","info4","info5","info6","info7","info8"], "number": [1,2,3,4,5,6,7,8] } 

Ahora me gustaría dividirlo en dos por id , manteniendo la info y el number respectivos. Es decir, tener dos dicts data1 y data2 .

Nota: esto es simplemente una muestra, hay varias claves en el dictado y me gustaría evitar el uso de los nombres de las claves, sino un bucle a través de todas ellas.

¿Qué es una forma pythonica de hacerlo?

Con listas de comprensión:

 data1 = [ data["info"][idx] for idx, x in enumerate(data["id"]) if x == 1 ] #data1 = ['info1', 'info2', 'info5', 'info7'] 

Si quieres recuperar todas las claves:

 data1 = [ { key : data[key][idx] for key in data.keys() } for idx, x in enu merate(data["id"]) if x == 1 ] >>> data1 [{'info': 'info1', 'id': 1, 'number': 1}, {'info': 'info2', 'id': 1, 'number': 2 }, {'info': 'info5', 'id': 1, 'number': 5}, {'info': 'info7', 'id': 1, 'number': 7}] 

Para trabajar con registros, personalmente me gusta numpy.recarray .

 In [3]: import numpy as np In [4]: fields = data.keys() In [8]: recs = zip(*[ lst for k, lst in data.iteritems() ]) In [9]: recs[0] Out[9]: ('info1', 1, 1) In [10]: recs[1] Out[10]: ('info2', 1, 2) In [21]: ra = np.rec.fromrecords(recs, names = fields ) In [17]: ra rec.array([('info1', 1, 1), ('info2', 1, 2), ('info3', 2, 3), ('info4', 2, 4), ('info5', 1, 5), ('info6', 2, 6), ('info7', 1, 7), ('info8', 2, 8)], dtype=[('info', 'S5'), ('id', ' 

Si desea agrupar los registros por id en un dict, haga:

 { id: ra[ra.id == id] for id in set(ra.id) } 
 >>> from collections import defaultdict >>> res = defaultdict(list) >>> for ID,info in zip(data["id"],data["info"]): res[ID].append(info) >>> res defaultdict(, {1: ['info1', 'info2', 'info5', 'info7'], 2: ['info3', 'info4', 'info6', 'info8']}) >>> 
 from collections import defaultdict ids = data.pop('id') databyid = defaultdict(lambda: defaultdict(list)) for id, values in zip(ids, zip(*data.values())): for kid, kval in enumerate(data.keys()): databyid[id][kval].append(values[kid]) 

Si necesita datos en estado original (con id):

  data['id'] = ids 

resultado:

 >>> databyid[1] defaultdict(, {'info': ['info1', 'info2', 'info5', 'info7'], 'number': [1, 2, 5, 7]}) >>> databyid[2] defaultdict(, {'info': ['info3', 'info4', 'info6', 'info8'], 'number': [3, 4, 6, 8]}) >>>