Elisa Rosati Elisa Rosati - 3 months ago 53
Python Question

python: sorting 3 levels nested dictionaries

my dictionary looks like:

{modID1:{sequences1:{header1:count1},sequences2:{header2:count2}...},
modID2:{sequences1:{header1:count1},sequences2:{header2:count2}...}....}


I want to reverse sort the "sequences" by "count",
example:

{modID1:
{sequences1:{header1: 3},sequences2:{header2:5},
sequences3: {header3:1}...},
modID2:{sequences1:{header1:1},sequences2:{header2:8},...},
....}


Wanted output:

{modID1:
{sequences2:{header2:5},sequences1:{header1: 3},
sequences3:{header3:1}...},
modID2:{sequences2:{header2:8},sequences1:{header1:1},...},
....}


I already saw some posts and I was trying to use something like:

for k,v in Dic.iteritems():
sorted=OrderedDict(sorted(v.iteritems(), key=lambda h: v[seq for seq in v][header], reverse=True))


But I guess I didn't get completely the usage of this function so is not working. Suggestions?

Thank you in advance

Answer

python 3 example

d = {
"modID1":
    {
        "sequences1": {"header1": 3},
        "sequences2": {"header2": 5},
        "sequences3": {"header3": 1}
    },
"modID2":
    {
        "sequences1": {"header1": 1},
        "sequences2": {"header2": 8},
    },
}
result = {
    k: OrderedDict(
        sorted(
            v.items(),  # "sequences1": {"header1": 3},"sequences2":     {"header2": 5},"sequences3": {"header3": 1}
            key=lambda h: next(  # h is  (sequences1,{"header1": 3})
                iter(
                    h[1].values()  # h[1] is {"header1": 3}
                )
            ),
            reverse=True
        )
    ) for k, v in d.items()}

print(result)

output is

{'modID1': OrderedDict([('sequences2', {'header2': 5}), ('sequences1', {'header1': 3}), ('sequences3', {'header3': 1})]), 'modID2': OrderedDict([('sequences2', {'header2': 8}), ('sequences1', {'header1': 1})])}

i changed your lambda function from lambda h: v[seq for seq in v][header] to lambda h: next(iter(h[1].values())

  1. h is ("sequences", {"header": count})
  2. h[1] is {"header": count}
  3. next(iter(h[1].values()) first value of {"header": count} getting first value of dict
  4. first value of {"header": count} is count

in python 3 items() work like iteritems() dict.items() and dict.iteritems()