繁体   English   中英

将字典列表拆分为多个字典列表

[英]Splitting a list of dictionaries into several lists of dictionaries

我一直在打扰这一段时间无济于事......任何帮助都会非常感激。

我有:

[{'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 = ...

使用defaultdict

import collections

result = collections.defaultdict(list)

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

result_list = result.values()        # Python 2.x
result_list = list(result.values())  # Python 3

这样,您不必对有多少不同事件或是否有任何事件缺失做出任何假设。

这会为您提供列表清单。 如果你想要一个由事件索引的dict ,我可能会使用dict(d)如果你打算做任何随机访问。

至于构建一堆个别列表,我认为这是一个坏主意。 它必须将它们创建为全局或使用eval (或以其他方式获得hacky),除非你确切地知道你声称不会有多少。 最好将它们放在容器中。

由于排序,这个是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}]
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的代码)。

我认为你真正想要的是过滤它们:

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}

在我看来,一个简单的实现就足够了:

grouping = {}    
for d in dictlist:
    if d[field] not in grouping:
        grouping[d[field]] = []
    grouping[d[field]].append(d)
result = list(result.values())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM