0

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

Elisa Rosati
  • 1
  • 1
  • 3
  • You want an `OrderedDict` containing other `OrderedDict`s. At the moment you are creating an `OrderedDict` containing `dict`s – Andrea Corbellini Jan 21 '16 at 16:49
  • You also hide the `sorted` builtin by the assignment to `sorted`, so second time around the loop everything will break. And do you really have dictionaries of just a single key, value pair at the bottom - wouldn't a tuple do? – AChampion Jan 21 '16 at 17:01
  • The {header:count} at the bottom is modified during the Dic creation, in practice the "count" starts from 1, and can increase. There is a way to maybe transform it in a tuple after Dic is created? Or I can modify the tuple from the beginning? – Elisa Rosati Jan 22 '16 at 06:37

2 Answers2

0

Assuming the you don't care about the order of the outer dict and just the inner dicts of sequences then you can do this:

>>> from collections import OrderedDict
>>> data = {'modID1': {'sequences2':{'header2':5}, 'sequences1':{'header1': 3},
...                    'sequences3':{'header3':1}},
...         'modID2': {'sequences2':{'header2':8},'sequences1':{'header1': 1}}}
>>> {k: OrderedDict(sorted(v.items(), key=lambda x: -sum(x[1].values()))) 
...  for k, v in data.items()}
{'modID1': OrderedDict([('sequences2', {'header2': 5}), ('sequences1', {'header1': 3}),
                        ('sequences3', {'header3': 1})]),
 'modID2': OrderedDict([('sequences2', {'header2': 8}), ('sequences1', {'header1': 1})])}
AChampion
  • 29,683
  • 4
  • 59
  • 75
0

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()

Community
  • 1
  • 1