2013-04-19 2 views
3

У меня есть словарь с данными той же длины (но разных типов), что-то вроде:Расщепление ДИКТ по ​​значению одного из ключей

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

Теперь я хотел бы разделить его на две части по id, сохраняя соответствующие info и number. То есть иметь два dicts data1 и data2.

Примечание: это всего лишь образец, есть несколько ключей в dict, и я бы хотел избежать использования имен ключей, но, скорее, перечеркнул их все.

Что такое Pythonic способ сделать это?

+2

Является ли это текстовым файлом, который нужно разобрать, или это настоящий словарь на языке python? –

+3

И если это настоящий словарь, вы можете разместить его в форме словаря? – jamylak

+0

Фактический словарь – sashkello

ответ

2

со списками на понимание:

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

Если вы хотите, чтобы восстановить все ключи:

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

Хорошо, приятель! Короче и точно, что мне нужно :) – sashkello

0
>>> from collections import defaultdict 
>>> res = defaultdict(list) 
>>> for ID,info in zip(data["id"],data["info"]): 
    res[ID].append(info) 


>>> res 
defaultdict(<type 'list'>, {1: ['info1', 'info2', 'info5', 'info7'], 2: ['info3', 'info4', 'info6', 'info8']}) 
>>> 
+0

Кроме того, на самом деле есть несколько столбцов (> 5, поэтому не легко их использовать) – sashkello

1

Для работы с записями, я лично, как 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', '<i8'), ('number', '<i8')]) 

In [23]: ra[ra.id == 2] 
rec.array([('info3', 2, 3), ('info4', 2, 4), ('info6', 2, 6), ('info8', 2, 8)], 
     dtype=[('info', 'S5'), ('id', '<i8'), ('number', '<i8')]) 

In [24]: ra[ra.id == 2].number 
Out[24]: array([3, 4, 6, 8]) 

In [25]: ra[ra.id == 2][0] 
Out[25]: ('info3', 2, 3) 

In [26]: ra[ra.id == 2][0].number 
Out[26]: 3 

Если вы хотите сгруппировать записи по идентификатору в Словаре, сделайте следующее:

{ id: ra[ra.id == id] for id in set(ra.id) } 
+0

Не знаю об этом, выглядит полезно! Благодарю. – sashkello

0
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]) 

если вам нужны данные в исходном состоянии (с удостоверением):

data['id'] = ids 

результат:

>>> databyid[1] 
defaultdict(<type 'list'>, {'info': ['info1', 'info2', 'info5', 'info7'], 'number': [1, 2, 5, 7]}) 
>>> databyid[2] 
defaultdict(<type 'list'>, {'info': ['info3', 'info4', 'info6', 'info8'], 'number': [3, 4, 6, 8]}) 
>>> 
Смежные вопросы