Muhammad Raghib
Muhammad Raghib

Reputation: 97

Sort nested defaultdict

I have a nested dictionary:

nestedDict = defaultdict(lambda:defaultdict(list))

it has values of the form:

termId: {
    'docId': [position1, position2, position3, position4],
    'docId': [position1, position2, position3, position4]
}

eg:

95074715468325493716883841120098961347 defaultdict(<class 'list'>, 
{'193083866963132215734985636049608586841': [1922, 1948, 1952, 1954], 
 '39188502589169058624219974133946618900': [1922, 1948, 1952, 1954]}) 

I want to sort it on the basis of docId in ascending order as

For Example:

1: {1:[1,2,3],2:[1,3,4],3:[1,3,4]} //docId should be in ascending order in each row

2: {1:[1,2,3],2:[1,3,4],3:[1,3,4]}

I am trying this:

orderedDict = OrderedDict(sorted(nestedDict.items(), key=lambda t: nestedDict[1][0]))

I know this is wrong but I don't know how to get it right. I am new to python.Sorry for asking this basic question.

Upvotes: 0

Views: 416

Answers (1)

pylang
pylang

Reputation: 44545

EDIT: We rebuild the dictionary around an ordered inner dict.

Given

import collections as ct


nested_dict = ct.defaultdict(lambda: ct.defaultdict(list))
d = {95074715468325493716883841120098961347:
     {
        "193083866963132215734985636049608586841": [1922, 1948, 1952, 1954], 
        "39188502589169058624219974133946618900": [1921, 1948, 1952, 1954],
        "100" : [1923, 1948, 1952, 1954], 
    }
}
nested_dict.update(d)

Code

>>> {k: ct.OrderedDict(sorted(v.items(), key=lambda x: float(x[0]))) for k, v in nested_dict.items()}
{95074715468325493716883841120098961347: OrderedDict([
    ('100', [1923, 1948, 1952, 1954]),
    ('39188502589169058624219974133946618900', [1921, 1948, 1952, 1954]),
    ('193083866963132215734985636049608586841', [1922, 1948, 1952, 1954])])}

Details

The code for the OrderedDict sorts the inner dictionary by a key. Note: these keys are numeric strings and are thus sorted using the float() builtin: Example:

inner_dict = {
    "200": [], 
    "300": [], 
    "100": [],    
}

ct.OrderedDict(sorted(inner_dict.items(), key=lambda x: float(x[0])))
# OrderedDict([('100', []), ('200', []), ('300', [])])

The remaining dictionary comprehension rebuilds the dictionary around these sorted dicts. If you wish to maintain the outer defaultdict type, rebuild accordingly:

rebuilt_dict = ct.defaultdict(list)
for k, v in nested_dict.items():
    rebuilt_dict[k] = ct.OrderedDict(sorted(v.items(), key=lambda x: float(x[0])))

rebuilt_dict

Upvotes: 1

Related Questions