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

Posted

技术标签:

【中文标题】将字典列表拆分为多个字典列表【英文标题】:Splitting a list of dictionaries into several lists of dictionaries 【发布时间】:2011-05-04 17:59:36 【问题描述】:

我一直在努力解决这个问题,但无济于事......任何帮助都会非常有用 赞赏。

我有:

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

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

【参考方案2】:

使用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),除非您确切知道将有多少您声称不知道。最好将它们保存在容器中。

【讨论】:

【参考方案3】:

这个是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]

【讨论】:

【参考方案4】:

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

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

【讨论】:

【参考方案5】:
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

如果您知道“事件”键是连续的从零开始的整数,则可以使用列表代替,但额外的复杂性可能不会为您带来任何好处。

python 2.5 中添加了 defaultdict,但早期版本的解决方法并不难(参见 Nick D 的代码)。

【讨论】:

以上是关于将字典列表拆分为多个字典列表的主要内容,如果未能解决你的问题,请参考以下文章

将列表转换为 DataFrame 并在 DataFrame 列中拆分嵌套字典 - Python 3.6

python:将文件读取并拆分到字典列表中

如何将带有字典列表的熊猫列拆分为每个键的单独列

在 Python 中按键拆分字典

LeetCode--单词拆分

139. 单词拆分