Pythonic way to split a list of lists into a dictionary with long keys?
xs = [
[1,2,3,4],
[5,6,7,8],
[9,0,0,1],
[2,3],
[0],
[5,8,3,2,5,1],
[6,4],
[1,6,9,9,2,9]
]
""" expected output:
xs_dict = {
1: [[0]]
2: [[2,3],[6,4]]
4: [[1,2,3,4],[5,6,7,8],[9,0,0,1]]
6: [[5,8,3,2,5,1],[1,6,9,9,2,9]]
}
"""
I can do this for example
xs_dict = {}
for x in xs:
aux = xs_dict.get(len(x),[])
aux.append(x)
xs_dict[len(x)] = aux
print(xs_dict)
But I can't help but feel that there must be a more pythonic way to achieve this.
What is it?
source to share
from itertools import groupby
xs_dict = {
key: list(value)
for (key, value) in groupby(sorted(xs, key=len), len)
}
As discussed in the comments below, the required input sort is a step that is unnecessarily costly. For large inputs, this will slow down this algorithm more than necessary. Use @ hiroprotagonist's solution instead, or replace groupby(sorted(…), …)
with groupby()
one that can handle unsorted input.
source to share
you can use defaultdict
:
from collections import defaultdict
xs_dict = defaultdict(list)
for item in xs:
xs_dict[len(item)].append(item)
python dict
also has a nice method setdefault
(this way you don't need to import anything):
xs_dict = {}
for item in xs:
xs_dict.setdefault(len(item), []).append(item)
source to share
import pprint
from collections import defaultdict
from itertools import groupby
xs = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 0, 0, 1],
[2, 3],
[0],
[5, 8, 3, 2, 5, 1],
[6, 4],
[1, 6, 9, 9, 2, 9]
]
data = defaultdict(list)
for result, group in groupby(sorted(xs, key=len), len):
for item in group:
data[result].append(item)
pprint.pprint(dict(data))
Gives me
{1: [[0]],
2: [[2, 3], [6, 4]],
4: [[1, 2, 3, 4], [5, 6, 7, 8], [9, 0, 0, 1]],
6: [[5, 8, 3, 2, 5, 1], [1, 6, 9, 9, 2, 9]]}
source to share