2010-11-03 2 views
8

Я уклоняюсь от этого на какое-то время безрезультатно ... Любая помощь будет в значительной степени оценена .Разбиение списка словарей на несколько списков словарей

у меня есть:

[{'event': 0, 'voltage': 1, 'time': 0}, 
{'event': 0, 'voltage': 2, 'time': 1}, 
{'event': 1, 'voltage': 1, 'time': 2}, 
{'event': 1, 'voltage': 2, 'time': 3}, 
{'event': 2, 'voltage': 1, 'time': 4}, 
{'event': 2, 'voltage': 2, 'time': 5}, 
...] 

, и я хочу разделить этот список словарей до в случае, как это (может быть сколь угодно много событий):

list0 = [{'event': 0, 'voltage': 1, 'time': 0}, 
{'event': 0, 'voltage': 2, 'time': 1}] 

list1 = [{'event': 1, 'voltage': 1, 'time': 2}, 
{'event': 1, 'voltage': 2, 'time': 3}] 

list2 = [{'event': 2, 'voltage': 1, 'time': 4}, 
{'event': 2, 'voltage': 2, 'time': 5}] 

listN = ... 

ответ

10

использования defaultdict

import collections 

result = collections.defaultdict(list) 

for d in dict_list: 
    result[d['event']].append(d) 

result_list = result.values() 

Таким образом, вам не нужно делать какие-либо предположения о том, сколько разных событий есть или есть какие-либо события отсутствуют.

Это дает вам список списков. Если вы хотите проиндексировать событие dict, я бы, вероятно, использовал dict(d), если вы планируете делать произвольный доступ.

Что касается создания кучи отдельных списков, я думаю, что это плохая идея. Это потребует создания их в виде глобалов или использования eval (или взломать каким-либо другим способом), если вы точно не знаете, сколько из них будет, на что вы не утверждаете. Лучше всего держать их в контейнере.

+0

+1 Я не знал о defaultdict. Благодаря! – dusan

+0

Спасибо, это было очень полезно! – thenickname

1
dict_list = [{'event': 0, 'voltage': 1, 'time': 0}, 
{'event': 0, 'voltage': 2, 'time': 1}, 
{'event': 1, 'voltage': 1, 'time': 2}, 
{'event': 1, 'voltage': 2, 'time': 3}, 
{'event': 2, 'voltage': 1, 'time': 4}, 
{'event': 2, 'voltage': 2, 'time': 5}, 
] 

import collections 
dol = collections.defaultdict(list) 
for d in dict_list: 
    k = d["event"] 
    dol[k].append(d) 

print dol 

, если вы знаете, что ваши ключи «событие» являются последовательными целыми числами с нуля, вы можете использовать список вместо этого, но дополнительная сложность не может получить вам что-нибудь.

defaultdict был добавлен в python 2.5, но обходной путь для более ранних версий не сложно (см. Код Nick D).

1

Я думаю, что вы действительно хотите, чтобы фильтровать их:

elist = [{'event': 0, 'voltage': 1, 'time': 0}, 
{'event': 0, 'voltage': 2, 'time': 1}, 
{'event': 1, 'voltage': 1, 'time': 2}, 
{'event': 1, 'voltage': 2, 'time': 3}, 
{'event': 2, 'voltage': 1, 'time': 4}, 
{'event': 2, 'voltage': 2, 'time': 5}] 


from itertools import ifilter 

def get_events(elist, n): 
    return ifilter(lambda d: d['event'] == n , elist) 

for e in get_events(elist,0): 
    print e 

это решение не будет создавать дополнительные структуры. (Думаю, что в случае большого списка событий)

Другой очень хорошее решение заключается в использовании GroupBy:

from itertools import groupby 
from operator import itemgetter 
for group in groupby(elist, itemgetter('event')): 
    id, event_list = group 
    for e in event_list: 
     print e 

{'time': 0, 'event': 0, 'voltage': 1} 
{'time': 1, 'event': 0, 'voltage': 2} 
{'time': 2, 'event': 1, 'voltage': 1} 
{'time': 3, 'event': 1, 'voltage': 2} 
{'time': 4, 'event': 2, 'voltage': 1} 
{'time': 5, 'event': 2, 'voltage': 2} 
+0

Хорошая точка, спасибо! – thenickname

2

Это один O(n log n) из-за подобного, но я бы не слишком беспокоиться, если не являются лот элементов в списке.

Это список, который уже сортируется по событию, вы можете пропустить тип курса.

>>> from operator import itemgetter 
>>> from itertools import groupby 
>>> d=[{'event': 0, 'voltage': 1, 'time': 0}, 
... {'event': 0, 'voltage': 2, 'time': 1}, 
... {'event': 1, 'voltage': 1, 'time': 2}, 
... {'event': 1, 'voltage': 2, 'time': 3}, 
... {'event': 2, 'voltage': 1, 'time': 4}, 
... {'event': 2, 'voltage': 2, 'time': 5}] 
>>> groupby(sorted(d, key=itemgetter('event')), key=itemgetter('event')) 
<itertools.groupby object at 0xb78138c4> 
>>> for x in _: 
... print x[0], list(x[1]) 
... 
0 [{'time': 0, 'event': 0, 'voltage': 1}, {'time': 1, 'event': 0, 'voltage': 2}] 
1 [{'time': 2, 'event': 1, 'voltage': 1}, {'time': 3, 'event': 1, 'voltage': 2}] 
2 [{'time': 4, 'event': 2, 'voltage': 1}, {'time': 5, 'event': 2, 'voltage': 2}] 
Смежные вопросы