繁体   English   中英

在字典的特定键出现后将字典列表拆分为子列表

[英]Splitting list of dictionary into sublists after the occurence of particular key of dictionary

我有字典列表。 这些字典基本上每个都只有一个键值。

例如:

lst = [{'x': 23}, {'y': 23432}, {'z': 78451}, {'a': 564}, {'x': 45},
       {'y': 7546}, {'a': 4564}, {'x': 54568}, {'y': 4515}, {'z': 78457}, 
       {'b': 5467}, {'a': 784}]

我试图在每次出现具有特定键"a"的字典后将字典列表lst划分为子列表。

我尝试使用我在互联网上看到的其他方式,但由于我是 Python 新手,我无法理解它们并获得所需的结果。 我希望最终结果如下所示:

final_lst = [
    [{'x': 23}, {'y': 23432}, {'z': 78451}, {'a': 564}],
    [{'x': 45}, {'y': 7546}, {'a': 4564}],
    [{'x': 54568}, {'y': 4515}, {'z': 78457}, {'b': 5467}, {'a': 784}]],
]

您可以使用生成器收集元素并在满足条件时产生:

def split_by_key(lst, key):
    collected = []
    for d in lst:
        collected.append(d)
        if key in d:
            yield collected
            collected = []
    if collected:  # yield any remainder
        yield collected

final_lst = list(split_by_key(lst, 'a'))

演示:

>>> lst = [{'x': 23}, {'y': 23432}, {'z': 78451}, {'a': 564}, {'x': 45},
...        {'y': 7546}, {'a': 4564}, {'x': 54568}, {'y': 4515}, {'z': 78457},
...        {'b': 5467}, {'a': 784}]
>>> list(split_by_key(lst, 'a'))
[[{'x': 23}, {'y': 23432}, {'z': 78451}, {'a': 564}], [{'x': 45}, {'y': 7546}, {'a': 4564}], [{'x': 54568}, {'y': 4515}, {'z': 78457}, {'b': 5467}, {'a': 784}]]
>>> pprint(_)
[[{'x': 23}, {'y': 23432}, {'z': 78451}, {'a': 564}],
 [{'x': 45}, {'y': 7546}, {'a': 4564}],
 [{'x': 54568}, {'y': 4515}, {'z': 78457}, {'b': 5467}, {'a': 784}]]

这是一个简单的解决方案:

result = []

for item in lst:
    if not result or 'a' in result[-1][-1]:
        result.append([])

    result[-1].append(item)

让我们试试itertools.groupby

import itertools

lst2 = []
for i, (_, g) in enumerate(itertools.groupby(lst, key=lambda x: not x.keys() - {'a'})):
     if not i % 2:
        lst2.append([])
     lst2[-1].extend(list(g))

lst2 
[[{'x': 23}, {'y': 23432}, {'z': 78451}, {'a': 564}],
 [{'x': 45}, {'y': 7546}, {'a': 4564}],
 [{'x': 54568}, {'y': 4515}, {'z': 78457}, {'b': 5467}, {'a': 784}]]

您可以从条件理解中将每个分区的分隔索引对zip在一起。 然后你理解适当的切片:

splits = [i for i, d in enumerate(lst, 1) if 'a' in d]
final_lst = [lst[start: end] for start, end in zip([0] + splits, splits)]
# final_lst
# [[{'x': 23}, {'y': 23432}, {'z': 78451}, {'a': 564}], [{'x': 45}, {'y': 7546}, {'a': 4564}], [{'x': 54568}, {'y': 4515}, {'z': 78457}, {'b': 5467}, {'a': 784}]]

有关enumeratezip文档。

只是为了添加到一堆,这将是基于x而不是a解决方案:

lst = [{'x':23}, {'y':23432}, {'z':78451}, {'a':564}, {'x':45}, {'y':7546},
       {'a':4564}, {'x':54568}, {'y':4515}, {'z':78457}, {'b':5467}, {'a':784}]

result = []
temp = []

breaker = 'x'

for i, item in enumerate(lst):
    if item.keys() != [breaker]:  
        temp.append(item)
    else:
        if i == 0:
            temp.append(item)
        else:
            result.append(temp)
            temp = [item]
    if i == len(lst)-1:
        result.append(temp)

暂无
暂无

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

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