Reputation: 73
I have list of dictionaries. These dictionaries basically have just one key-value each.
For example:
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}]
I am trying to divide the list of dictionaries lst
into sublists after every occurrence of a dictionary with a specific key "a"
.
I tried using other ways that I saw on the internet but as I am new to python, I am not able to understand them and get the desired result. I want the final result to look like:
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}]],
]
Upvotes: 7
Views: 1279
Reputation: 30453
Here is a straightforward solution:
result = []
for item in lst:
if not result or 'a' in result[-1][-1]:
result.append([])
result[-1].append(item)
Upvotes: 3
Reputation: 27869
Just to add to bunch, this would be solution based on x
instead of 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)
Upvotes: 0
Reputation: 73460
You can zip
together pairs of delimiting indexes of each partition from a conditional comprehension. Then you comprehend the appropriate slices:
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}]]
Upvotes: 1
Reputation: 402423
Let's try 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}]]
Upvotes: 1
Reputation: 1121744
You can use a generator that collects elements and yields when the condition is met:
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'))
Demo:
>>> 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}]]
Upvotes: 6