Reputation: 89
I have a list of lists that looks like this:
big_list = [[0,5,70],[0,3,20],[0,4,60],[0,6,30],
[1,6,50],[1,4,30],[1,3,70],
[2,4,20],[2,5,40],
[69,420,20]]
How do I turn it into this list, where all of the lists are grouped together into lists by the first number in every list:
big_list_sorted = [[[0,5,70],[0,3,20],[0,4,60],[0,6,30]],
[[1,6,50],[1,4,30],[1,3,70]],
[[2,4,20],[2,5,40]],
[[69,420,20]]]
Also, here I put lists in the original big_list in order for readability, but they would not be in order.
Upvotes: 2
Views: 3527
Reputation: 53029
It's a minor stylistic thing but you can avoid the ugly lambda x: x[0]
many answers are opting for and use operator.itemgetter
instead.
from random import shuffle
from itertools import groupby
from operator import itemgetter
big_list = [[0,5,70],[0,3,50],[0,4,60],[0,6,30],
[1,6,50],[1,4,30],[1,3,70],
[2,4,20],[2,5,40],
[69,420,20]]
shuffle(big_list)
[*map(list,map(itemgetter(1),groupby(sorted(big_list),itemgetter(0))))]
# [[[0, 3, 50], [0, 4, 60], [0, 5, 70], [0, 6, 30]], [[1, 3, 70], [1, 4, 30], [1, 6, 50]], [[2, 4, 20], [2, 5, 40]], [[69, 420, 20]]]
Upvotes: 0
Reputation: 41116
You could use [Python 3.Docs]: itertools - Functions creating iterators for efficient looping.
Group the (inner) lists (via groupby), on their 1st element, in the sorted initial list:
>>> import itertools >>> >>> big_list [[0, 5, 70], [0, 3, 50], [0, 4, 60], [0, 6, 30], [1, 6, 50], [1, 4, 30], [1, 3, 70], [2, 4, 20], [2, 5, 40], [69, 420, 20]] >>> >>> [list(item[1]) for item in itertools.groupby(sorted(big_list), key=lambda x: x[0])] [[[0, 3, 50], [0, 4, 60], [0, 5, 70], [0, 6, 30]], [[1, 3, 70], [1, 4, 30], [1, 6, 50]], [[2, 4, 20], [2, 5, 40]], [[69, 420, 20]]]
As a side note (might be a typo), the 1st element in the desired output ([0, 3, 20]
) is not present in the input.
Upvotes: 1
Reputation: 12990
You can group lists in a dictionary by their first element and get the result using .values()
:
groups = {}
for l in big_list:
groups.setdefault(l[0], []).append(l)
big_list_sorted = list(groups.values())
print(big_list_sorted)
# [[[0, 5, 70], [0, 3, 50], [0, 4, 60], [0, 6, 30]], [[1, 6, 50], [1, 4, 30], [1, 3, 70]], [[2, 4, 20], [2, 5, 40]], [[69, 420, 20]]]
Upvotes: 5
Reputation: 8247
You can use itertools.groupby
to accomplish this.
First you sort the array by the first element.
big_list = sorted(big_list)
Next you apply groupby
to split them into subarrays keyed on the first element.
itertools.groupby(big_list, key=lambda x:x[0])
At this point you have something that looks like
[(0, <itertools._grouper object at 0x107bcf390>), (1, <itertools._grouper object at 0x107bcf310>), (2, <itertools._grouper object at 0x107bcf250>), (69, <itertools._grouper object at 0x107bcf2d0>)]
In the tuple, the grouper objects at index 1 contains the elements matching the key at index 0. Now you can just create an array using index 1 of each tuple.
[list(g) for i, g in itertools.groupby(big_list, lambda x: x[0])]
Upvotes: 1
Reputation: 623
You need a custom sort based on the first element of each list.
big_list.sort(key=lambda x: x[0])
You can read about sorting here: https://wiki.python.org/moin/HowTo/Sorting
Upvotes: -1
Reputation: 4140
You can use itertools.groupby
>>> from itertools import groupby
>>> [list(g) for _, g in groupby(big_list, lambda l: l[0])]
[[[0, 5, 70], [0, 3, 50], [0, 4, 60], [0, 6, 30]], [[1, 6, 50], [1, 4, 30], [1, 3, 70]], [[2, 4, 20], [2, 5, 40]], [[69, 420, 20]]]
Note: you can void to use list
, it's there only to make the output more readable as groupby returns an iterator.
Upvotes: 1