How to set sort predicate in sortedcontainers.SortedDict?

770 Views Asked by At

Is there a way to sort items in sortedcontainers.SortedDict by value, so that SortedDict always maintains its items in sorted order based on values, not on keys?

The standard example from sortedcontainers shows that items in SortedDict will be automatically sorted by dictionary key:

>>> from sortedcontainers import SortedDict
>>> sd = SortedDict({'c': 3, 'a': 1, 'b': 2})
>>> sd
SortedDict({'a': 1, 'b': 2, 'c': 3})

So far, I managed to sort items in dict by value(datetime) during creation time:

>>> import datetime
>>> from sortedcontainers import SortedDict
>>> d = {'a': {'datetime': datetime.datetime.now()}, 'b': {'datetime': datetime.datetime.now()}, 'z': {'datetime': datetime.datetime.now()}, 'c': {'datetime': datetime.datetime.now()}}
>>> sd = SortedDict(lambda key: d[key]['datetime'], d)
>>> sd
SortedDict(<function <lambda> at 0x101e86598>, {'a': {'datetime': datetime.datetime('...')}, 'b': {'datetime': datetime.datetime('...')}, 'z': {'datetime': datetime.datetime('...')}, 'e': {'datetime': datetime.datetime('...')}})

However, when I'm trying to add a new item, it throws the key error exception:

>>> sd['d'] = {'datetime': datetime.datetime.now()}
>>> KeyError: 'd'
1

There are 1 best solutions below

0
On

I'm new to sortedcontainers, but my impression is this is not possible as such. Have a look instead at the related package Sorted Collections and specifically ValueSortedDict. You will need to refactor your code a bit, but you could do something like:

d = {'a': {'datetime': datetime.datetime.now()}, 'b': {'datetime': datetime.datetime.now()}, 'z': {'datetime': datetime.datetime.now()}, 'c': {'datetime': datetime.datetime.now()}}
vsd = ValueSortedDict()
for k, v in d.items():                                                                                                                                              
    vsd[k] = v['datetime']
vsd['d'] = datetime.datetime.now()